mpeg3.cpp
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:6k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is MPEG4IP.
  13.  * 
  14.  * The Initial Developer of the Original Code is Cisco Systems Inc.
  15.  * Portions created by Cisco Systems Inc. are
  16.  * Copyright (C) Cisco Systems Inc. 2000, 2001.  All Rights Reserved.
  17.  * 
  18.  * Contributor(s): 
  19.  *              Bill May        wmay@cisco.com
  20.  */
  21. /*
  22.  * raw video codec
  23.  */
  24. #include "mpeg3.h"
  25. #include <mpeg3videoprotos.h>
  26. #include <bitstream.h>
  27. #include "mp4av.h"
  28. //#define DEBUG_MPEG3_FRAME 1
  29. static codec_data_t *mpeg3_create (format_list_t *media_fmt,
  30.    video_info_t *vinfo,
  31.    const uint8_t *userdata,
  32.    uint32_t ud_size,
  33.    video_vft_t *vft,
  34.    void *ifptr)
  35. {
  36.   mpeg3_codec_t *mpeg3;
  37.   mpeg3 = (mpeg3_codec_t *)malloc(sizeof(mpeg3_codec_t));
  38.   memset(mpeg3, 0, sizeof(*mpeg3));
  39.   mpeg3->m_vft = vft;
  40.   mpeg3->m_ifptr = ifptr;
  41.   mpeg3->m_video = mpeg3video_new(0, 1);
  42.   mpeg3->m_did_pause = 1;
  43.   return ((codec_data_t *)mpeg3);
  44. }
  45. static void mpeg3_close (codec_data_t *ifptr)
  46. {
  47.   mpeg3_codec_t *mpeg3;
  48.   mpeg3 = (mpeg3_codec_t *)ifptr;
  49.   if (mpeg3->m_video) {
  50.     mpeg3video_delete(mpeg3->m_video);
  51.     mpeg3->m_video = NULL;
  52.   }
  53.   free(mpeg3);
  54. }
  55. static void mpeg3_do_pause (codec_data_t *ifptr)
  56. {
  57.   mpeg3_codec_t *mpeg3 = (mpeg3_codec_t *)ifptr;
  58.   mpeg3->m_did_pause = 1;
  59.   mpeg3->m_got_i = 0;
  60.   mpeg3->m_video->repeat_count = mpeg3->m_video->current_repeat = 0;
  61. }
  62. static int mpeg3_frame_is_sync (codec_data_t *ifptr, 
  63. uint8_t *buffer, 
  64. uint32_t buflen,
  65. void *userdata)
  66. {
  67.   int ret;
  68.   ret = MP4AV_Mpeg3FindGopOrPictHdr(buffer, buflen, NULL);
  69.   if (ret >= 0) {
  70.     mpeg3_do_pause(ifptr);
  71.     return 1;
  72.   }
  73.   return 0;
  74. }
  75. static int mpeg3_decode (codec_data_t *ptr,
  76. uint64_t ts, 
  77. int from_rtp,
  78. int *sync_frame,
  79. uint8_t *buffer, 
  80. uint32_t buflen,
  81.  void *ud)
  82. {
  83.   int ret;
  84.   int render = 1;
  85.   mpeg3_codec_t *mpeg3 = (mpeg3_codec_t *)ptr;
  86.   mpeg3video_t *video;
  87.   video = mpeg3->m_video;
  88.   buffer[buflen] = 0;
  89.   buffer[buflen + 1] = 0;
  90.   buffer[buflen + 2] = 1;
  91.   buffer[buflen + 3] = 0;
  92. #if 0
  93.   mpeg3->m_vft->log_msg(LOG_DEBUG, "mpeg3", "ts %llu", ts);
  94.   //if (mpeg3->m_did_pause != 0) 
  95.  {
  96.     for (uint32_t ix = 0; ix < buflen + 3; ix++) {
  97.       if (buffer[ix] == 0 &&
  98.   buffer[ix + 1] == 0 &&
  99.   buffer[ix + 2] == 1) {
  100. mpeg3->m_vft->log_msg(LOG_DEBUG, "mpeg3", "index %d - value %x %x %x", 
  101.       ix, buffer[ix + 3], buffer[ix + 4],
  102.       buffer[ix + 5]);
  103.       }
  104.     }
  105.   }
  106. #endif
  107.   mpeg3bits_use_ptr_len(video->vstream, (unsigned char *)buffer, buflen + 3);
  108.   if (video->decoder_initted == 0) {
  109.     mpeg3video_get_header(video, 1);
  110.     if (video->found_seqhdr != 0) {
  111.       mpeg3video_initdecoder(video);
  112.       video->decoder_initted = 1;
  113.       mpeg3->m_h = video->vertical_size;
  114.       mpeg3->m_w = video->horizontal_size;
  115.       mpeg3->m_vft->video_configure(mpeg3->m_ifptr, 
  116.     mpeg3->m_w,
  117.     mpeg3->m_h,
  118.     VIDEO_FORMAT_YUV);
  119.       // Gross and disgusting, but it looks like it didn't clean up
  120.       // properly - so just start from beginning of buffer and decode.
  121.     } else {
  122.       mpeg3->m_vft->log_msg(LOG_DEBUG, "mpeg3", "didnt find seq header in frame %llu", ts);
  123.       return buflen;
  124.     }
  125.     mpeg3->m_did_pause = 1;
  126.     mpeg3->m_got_i = 0;
  127.   } 
  128.     if (mpeg3->m_did_pause) {
  129.       if (mpeg3->m_got_i == 0) {
  130. int ret;
  131.   ret = MP4AV_Mpeg3FindGopOrPictHdr(buffer, buflen, NULL);
  132. if (ret >= 0) {
  133.   mpeg3->m_got_i = 1;
  134.   render = 0;
  135. } else
  136.   return (buflen);
  137.       } else {
  138. mpeg3->m_got_i++;
  139. if (mpeg3->m_got_i == 4) {
  140.   mpeg3->m_did_pause = 0;
  141. } else {
  142.   render = 0;
  143. }
  144.       }
  145.     }
  146.   char *y, *u, *v;
  147. #if 0
  148.   if (from_rtp) {
  149.     int ftype;
  150.     ret = MP4AV_Mpeg3FindGopOrPictHdr(buffer, buflen, &ftype);
  151.     if (ret <= 0) {
  152.       mpeg3->m_vft->log_msg(LOG_DEBUG, "mpeg3", "frame %llu - type %d", 
  153.     ts, ftype);
  154.     } else {
  155.       mpeg3->m_vft->log_msg(LOG_DEBUG, "mpeg3", "frame %llu - return %d", 
  156.     ts, ret);
  157.     }
  158.       
  159.   }
  160. #endif
  161.       
  162.     
  163.   y = NULL;
  164.   ret = mpeg3video_read_yuvframe_ptr(video,
  165.      (unsigned char *)buffer,
  166.      buflen + 3,
  167.      &y,
  168.      &u,
  169.      &v);
  170.   if (ret == 0 && y != NULL && render != 0) {
  171. #ifdef DEBUG_MPEG3_FRAME
  172.     mpeg3->m_vft->log_msg(LOG_DEBUG, "mpeg3", "frame %llu decoded", 
  173.   ts);
  174. #endif
  175.     ret = mpeg3->m_vft->video_have_frame(mpeg3->m_ifptr,
  176.  (const uint8_t *)y, 
  177.  (const uint8_t *)u, 
  178.  (const uint8_t *)v, 
  179.  mpeg3->m_w, mpeg3->m_w / 2, 
  180.  mpeg3->cached_ts);
  181.     mpeg3->cached_ts = ts;
  182.   } else {
  183. #ifdef DEBUG_MPEG3_FRAME
  184.     if (render == 0) {
  185.       mpeg3->m_vft->log_msg(LOG_DEBUG, "mpeg3", "skip render");
  186.     }
  187.     mpeg3->m_vft->log_msg(LOG_DEBUG, "mpeg3", "frame %llu ret %d %p", 
  188.   ts, ret, y);
  189. #endif
  190.     mpeg3->cached_ts = ts;
  191.   }
  192.     
  193.   return (buflen);
  194. }
  195. static int mpeg3_codec_check (lib_message_func_t message,
  196.      const char *compressor,
  197.      int type,
  198.      int profile,
  199.      format_list_t *fptr,
  200.      const uint8_t *userdata,
  201.      uint32_t userdata_size)
  202. {
  203.   if (fptr != NULL) {
  204.     if (strcmp(fptr->fmt, "32") == 0) {
  205.       return 1;
  206.     }
  207.   }
  208.   if (compressor != NULL && strcmp(compressor, "MPEG FILE") == 0) {
  209.     return 1;
  210.   }
  211.   return -1;
  212. }
  213. VIDEO_CODEC_PLUGIN("mpeg3", 
  214.    mpeg3_create,
  215.    mpeg3_do_pause,
  216.    mpeg3_decode,
  217.    NULL,
  218.    mpeg3_close,
  219.    mpeg3_codec_check,
  220.    mpeg3_frame_is_sync);