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