00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "parser.h"
00024 #include "mpegvideo.h"
00025
00026 static void mpegvideo_extract_headers(AVCodecParserContext *s,
00027 AVCodecContext *avctx,
00028 const uint8_t *buf, int buf_size)
00029 {
00030 ParseContext1 *pc = s->priv_data;
00031 const uint8_t *buf_end = buf + buf_size;
00032 uint32_t start_code;
00033 int frame_rate_index, ext_type, bytes_left;
00034 int frame_rate_ext_n, frame_rate_ext_d;
00035 int top_field_first, repeat_first_field, progressive_frame;
00036 int horiz_size_ext, vert_size_ext, bit_rate_ext;
00037 int did_set_size=0;
00038
00039 s->repeat_pict = 0;
00040
00041 while (buf < buf_end) {
00042 start_code= -1;
00043 buf= avpriv_mpv_find_start_code(buf, buf_end, &start_code);
00044 bytes_left = buf_end - buf;
00045 switch(start_code) {
00046 case PICTURE_START_CODE:
00047 if (bytes_left >= 2) {
00048 s->pict_type = (buf[1] >> 3) & 7;
00049 }
00050 break;
00051 case SEQ_START_CODE:
00052 if (bytes_left >= 7) {
00053 pc->width = (buf[0] << 4) | (buf[1] >> 4);
00054 pc->height = ((buf[1] & 0x0f) << 8) | buf[2];
00055 if(!avctx->width || !avctx->height || !avctx->coded_width || !avctx->coded_height){
00056 avcodec_set_dimensions(avctx, pc->width, pc->height);
00057 did_set_size=1;
00058 }
00059 frame_rate_index = buf[3] & 0xf;
00060 pc->frame_rate.den = avctx->time_base.den = avpriv_frame_rate_tab[frame_rate_index].num;
00061 pc->frame_rate.num = avctx->time_base.num = avpriv_frame_rate_tab[frame_rate_index].den;
00062 avctx->bit_rate = ((buf[4]<<10) | (buf[5]<<2) | (buf[6]>>6))*400;
00063 avctx->codec_id = CODEC_ID_MPEG1VIDEO;
00064 avctx->sub_id = 1;
00065 }
00066 break;
00067 case EXT_START_CODE:
00068 if (bytes_left >= 1) {
00069 ext_type = (buf[0] >> 4);
00070 switch(ext_type) {
00071 case 0x1:
00072 if (bytes_left >= 6) {
00073 horiz_size_ext = ((buf[1] & 1) << 1) | (buf[2] >> 7);
00074 vert_size_ext = (buf[2] >> 5) & 3;
00075 bit_rate_ext = ((buf[2] & 0x1F)<<7) | (buf[3]>>1);
00076 frame_rate_ext_n = (buf[5] >> 5) & 3;
00077 frame_rate_ext_d = (buf[5] & 0x1f);
00078 pc->progressive_sequence = buf[1] & (1 << 3);
00079 avctx->has_b_frames= !(buf[5] >> 7);
00080
00081 pc->width |=(horiz_size_ext << 12);
00082 pc->height |=( vert_size_ext << 12);
00083 avctx->bit_rate += (bit_rate_ext << 18) * 400;
00084 if(did_set_size)
00085 avcodec_set_dimensions(avctx, pc->width, pc->height);
00086 avctx->time_base.den = pc->frame_rate.den * (frame_rate_ext_n + 1) * 2;
00087 avctx->time_base.num = pc->frame_rate.num * (frame_rate_ext_d + 1);
00088 avctx->codec_id = CODEC_ID_MPEG2VIDEO;
00089 avctx->sub_id = 2;
00090 }
00091 break;
00092 case 0x8:
00093 if (bytes_left >= 5) {
00094 top_field_first = buf[3] & (1 << 7);
00095 repeat_first_field = buf[3] & (1 << 1);
00096 progressive_frame = buf[4] & (1 << 7);
00097
00098
00099 s->repeat_pict = 1;
00100 if (repeat_first_field) {
00101 if (pc->progressive_sequence) {
00102 if (top_field_first)
00103 s->repeat_pict = 5;
00104 else
00105 s->repeat_pict = 3;
00106 } else if (progressive_frame) {
00107 s->repeat_pict = 2;
00108 }
00109 }
00110 }
00111 break;
00112 }
00113 }
00114 break;
00115 case -1:
00116 goto the_end;
00117 default:
00118
00119
00120 if (start_code >= SLICE_MIN_START_CODE &&
00121 start_code <= SLICE_MAX_START_CODE)
00122 goto the_end;
00123 break;
00124 }
00125 }
00126 the_end: ;
00127 }
00128
00129 static int mpegvideo_parse(AVCodecParserContext *s,
00130 AVCodecContext *avctx,
00131 const uint8_t **poutbuf, int *poutbuf_size,
00132 const uint8_t *buf, int buf_size)
00133 {
00134 ParseContext1 *pc1 = s->priv_data;
00135 ParseContext *pc= &pc1->pc;
00136 int next;
00137
00138 if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){
00139 next= buf_size;
00140 }else{
00141 next= ff_mpeg1_find_frame_end(pc, buf, buf_size, s);
00142
00143 if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
00144 *poutbuf = NULL;
00145 *poutbuf_size = 0;
00146 return buf_size;
00147 }
00148
00149 }
00150
00151
00152
00153 mpegvideo_extract_headers(s, avctx, buf, buf_size);
00154 av_dlog(NULL, "pict_type=%d frame_rate=%0.3f repeat_pict=%d\n",
00155 s->pict_type, (double)avctx->time_base.den / avctx->time_base.num, s->repeat_pict);
00156
00157 *poutbuf = buf;
00158 *poutbuf_size = buf_size;
00159 return next;
00160 }
00161
00162 static int mpegvideo_split(AVCodecContext *avctx,
00163 const uint8_t *buf, int buf_size)
00164 {
00165 int i;
00166 uint32_t state= -1;
00167 int found=0;
00168
00169 for(i=0; i<buf_size; i++){
00170 state= (state<<8) | buf[i];
00171 if(state == 0x1B3){
00172 found=1;
00173 }else if(found && state != 0x1B5 && state < 0x200 && state >= 0x100)
00174 return i-3;
00175 }
00176 return 0;
00177 }
00178
00179 AVCodecParser ff_mpegvideo_parser = {
00180 .codec_ids = { CODEC_ID_MPEG1VIDEO, CODEC_ID_MPEG2VIDEO },
00181 .priv_data_size = sizeof(ParseContext1),
00182 .parser_parse = mpegvideo_parse,
00183 .parser_close = ff_parse1_close,
00184 .split = mpegvideo_split,
00185 };