1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * MPEG-1 / MPEG-2 video parser 3cabdff1aSopenharmony_ci * Copyright (c) 2000,2001 Fabrice Bellard 4cabdff1aSopenharmony_ci * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * This file is part of FFmpeg. 7cabdff1aSopenharmony_ci * 8cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 9cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 10cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 11cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 12cabdff1aSopenharmony_ci * 13cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 14cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 15cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16cabdff1aSopenharmony_ci * Lesser General Public License for more details. 17cabdff1aSopenharmony_ci * 18cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 19cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 20cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21cabdff1aSopenharmony_ci */ 22cabdff1aSopenharmony_ci 23cabdff1aSopenharmony_ci#include "internal.h" 24cabdff1aSopenharmony_ci#include "parser.h" 25cabdff1aSopenharmony_ci#include "mpeg12.h" 26cabdff1aSopenharmony_ci#include "mpeg12data.h" 27cabdff1aSopenharmony_ci#include "startcode.h" 28cabdff1aSopenharmony_ci 29cabdff1aSopenharmony_cistruct MpvParseContext { 30cabdff1aSopenharmony_ci ParseContext pc; 31cabdff1aSopenharmony_ci AVRational frame_rate; 32cabdff1aSopenharmony_ci int progressive_sequence; 33cabdff1aSopenharmony_ci int width, height; 34cabdff1aSopenharmony_ci}; 35cabdff1aSopenharmony_ci 36cabdff1aSopenharmony_ci#if !FF_API_FLAG_TRUNCATED 37cabdff1aSopenharmony_ci/** 38cabdff1aSopenharmony_ci * Find the end of the current frame in the bitstream. 39cabdff1aSopenharmony_ci * @return the position of the first byte of the next frame, or -1 40cabdff1aSopenharmony_ci */ 41cabdff1aSopenharmony_cistatic int mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, 42cabdff1aSopenharmony_ci int buf_size, AVCodecParserContext *s) 43cabdff1aSopenharmony_ci{ 44cabdff1aSopenharmony_ci int i; 45cabdff1aSopenharmony_ci uint32_t state = pc->state; 46cabdff1aSopenharmony_ci 47cabdff1aSopenharmony_ci /* EOF considered as end of frame */ 48cabdff1aSopenharmony_ci if (buf_size == 0) 49cabdff1aSopenharmony_ci return 0; 50cabdff1aSopenharmony_ci 51cabdff1aSopenharmony_ci/* 52cabdff1aSopenharmony_ci 0 frame start -> 1/4 53cabdff1aSopenharmony_ci 1 first_SEQEXT -> 0/2 54cabdff1aSopenharmony_ci 2 first field start -> 3/0 55cabdff1aSopenharmony_ci 3 second_SEQEXT -> 2/0 56cabdff1aSopenharmony_ci 4 searching end 57cabdff1aSopenharmony_ci*/ 58cabdff1aSopenharmony_ci 59cabdff1aSopenharmony_ci for (i = 0; i < buf_size; i++) { 60cabdff1aSopenharmony_ci av_assert1(pc->frame_start_found >= 0 && pc->frame_start_found <= 4); 61cabdff1aSopenharmony_ci if (pc->frame_start_found & 1) { 62cabdff1aSopenharmony_ci if (state == EXT_START_CODE && (buf[i] & 0xF0) != 0x80) 63cabdff1aSopenharmony_ci pc->frame_start_found--; 64cabdff1aSopenharmony_ci else if (state == EXT_START_CODE + 2) { 65cabdff1aSopenharmony_ci if ((buf[i] & 3) == 3) 66cabdff1aSopenharmony_ci pc->frame_start_found = 0; 67cabdff1aSopenharmony_ci else 68cabdff1aSopenharmony_ci pc->frame_start_found = (pc->frame_start_found + 1) & 3; 69cabdff1aSopenharmony_ci } 70cabdff1aSopenharmony_ci state++; 71cabdff1aSopenharmony_ci } else { 72cabdff1aSopenharmony_ci i = avpriv_find_start_code(buf + i, buf + buf_size, &state) - buf - 1; 73cabdff1aSopenharmony_ci if (pc->frame_start_found == 0 && state >= SLICE_MIN_START_CODE && state <= SLICE_MAX_START_CODE) { 74cabdff1aSopenharmony_ci i++; 75cabdff1aSopenharmony_ci pc->frame_start_found = 4; 76cabdff1aSopenharmony_ci } 77cabdff1aSopenharmony_ci if (state == SEQ_END_CODE) { 78cabdff1aSopenharmony_ci pc->frame_start_found = 0; 79cabdff1aSopenharmony_ci pc->state = -1; 80cabdff1aSopenharmony_ci return i + 1; 81cabdff1aSopenharmony_ci } 82cabdff1aSopenharmony_ci if (pc->frame_start_found == 2 && state == SEQ_START_CODE) 83cabdff1aSopenharmony_ci pc->frame_start_found = 0; 84cabdff1aSopenharmony_ci if (pc->frame_start_found < 4 && state == EXT_START_CODE) 85cabdff1aSopenharmony_ci pc->frame_start_found++; 86cabdff1aSopenharmony_ci if (pc->frame_start_found == 4 && (state & 0xFFFFFF00) == 0x100) { 87cabdff1aSopenharmony_ci if (state < SLICE_MIN_START_CODE || state > SLICE_MAX_START_CODE) { 88cabdff1aSopenharmony_ci pc->frame_start_found = 0; 89cabdff1aSopenharmony_ci pc->state = -1; 90cabdff1aSopenharmony_ci return i - 3; 91cabdff1aSopenharmony_ci } 92cabdff1aSopenharmony_ci } 93cabdff1aSopenharmony_ci if (pc->frame_start_found == 0 && s && state == PICTURE_START_CODE) { 94cabdff1aSopenharmony_ci ff_fetch_timestamp(s, i - 3, 1, i > 3); 95cabdff1aSopenharmony_ci } 96cabdff1aSopenharmony_ci } 97cabdff1aSopenharmony_ci } 98cabdff1aSopenharmony_ci pc->state = state; 99cabdff1aSopenharmony_ci return END_NOT_FOUND; 100cabdff1aSopenharmony_ci} 101cabdff1aSopenharmony_ci#endif 102cabdff1aSopenharmony_ci 103cabdff1aSopenharmony_cistatic void mpegvideo_extract_headers(AVCodecParserContext *s, 104cabdff1aSopenharmony_ci AVCodecContext *avctx, 105cabdff1aSopenharmony_ci const uint8_t *buf, int buf_size) 106cabdff1aSopenharmony_ci{ 107cabdff1aSopenharmony_ci struct MpvParseContext *pc = s->priv_data; 108cabdff1aSopenharmony_ci const uint8_t *buf_end = buf + buf_size; 109cabdff1aSopenharmony_ci uint32_t start_code; 110cabdff1aSopenharmony_ci int frame_rate_index, ext_type, bytes_left; 111cabdff1aSopenharmony_ci int frame_rate_ext_n, frame_rate_ext_d; 112cabdff1aSopenharmony_ci int top_field_first, repeat_first_field, progressive_frame; 113cabdff1aSopenharmony_ci int horiz_size_ext, vert_size_ext, bit_rate_ext; 114cabdff1aSopenharmony_ci int did_set_size=0; 115cabdff1aSopenharmony_ci int set_dim_ret = 0; 116cabdff1aSopenharmony_ci int bit_rate = 0; 117cabdff1aSopenharmony_ci int vbv_delay = 0; 118cabdff1aSopenharmony_ci int chroma_format; 119cabdff1aSopenharmony_ci enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE; 120cabdff1aSopenharmony_ci//FIXME replace the crap with get_bits() 121cabdff1aSopenharmony_ci s->repeat_pict = 0; 122cabdff1aSopenharmony_ci 123cabdff1aSopenharmony_ci while (buf < buf_end) { 124cabdff1aSopenharmony_ci start_code= -1; 125cabdff1aSopenharmony_ci buf= avpriv_find_start_code(buf, buf_end, &start_code); 126cabdff1aSopenharmony_ci bytes_left = buf_end - buf; 127cabdff1aSopenharmony_ci switch(start_code) { 128cabdff1aSopenharmony_ci case PICTURE_START_CODE: 129cabdff1aSopenharmony_ci if (bytes_left >= 2) { 130cabdff1aSopenharmony_ci s->pict_type = (buf[1] >> 3) & 7; 131cabdff1aSopenharmony_ci if (bytes_left >= 4) 132cabdff1aSopenharmony_ci vbv_delay = ((buf[1] & 0x07) << 13) | (buf[2] << 5) | (buf[3] >> 3); 133cabdff1aSopenharmony_ci } 134cabdff1aSopenharmony_ci break; 135cabdff1aSopenharmony_ci case SEQ_START_CODE: 136cabdff1aSopenharmony_ci if (bytes_left >= 7) { 137cabdff1aSopenharmony_ci pc->width = (buf[0] << 4) | (buf[1] >> 4); 138cabdff1aSopenharmony_ci pc->height = ((buf[1] & 0x0f) << 8) | buf[2]; 139cabdff1aSopenharmony_ci if(!avctx->width || !avctx->height || !avctx->coded_width || !avctx->coded_height){ 140cabdff1aSopenharmony_ci set_dim_ret = ff_set_dimensions(avctx, pc->width, pc->height); 141cabdff1aSopenharmony_ci did_set_size=1; 142cabdff1aSopenharmony_ci } 143cabdff1aSopenharmony_ci pix_fmt = AV_PIX_FMT_YUV420P; 144cabdff1aSopenharmony_ci frame_rate_index = buf[3] & 0xf; 145cabdff1aSopenharmony_ci pc->frame_rate = avctx->framerate = ff_mpeg12_frame_rate_tab[frame_rate_index]; 146cabdff1aSopenharmony_ci bit_rate = (buf[4]<<10) | (buf[5]<<2) | (buf[6]>>6); 147cabdff1aSopenharmony_ci avctx->codec_id = AV_CODEC_ID_MPEG1VIDEO; 148cabdff1aSopenharmony_ci avctx->ticks_per_frame = 1; 149cabdff1aSopenharmony_ci } 150cabdff1aSopenharmony_ci break; 151cabdff1aSopenharmony_ci case EXT_START_CODE: 152cabdff1aSopenharmony_ci if (bytes_left >= 1) { 153cabdff1aSopenharmony_ci ext_type = (buf[0] >> 4); 154cabdff1aSopenharmony_ci switch(ext_type) { 155cabdff1aSopenharmony_ci case 0x1: /* sequence extension */ 156cabdff1aSopenharmony_ci if (bytes_left >= 6) { 157cabdff1aSopenharmony_ci horiz_size_ext = ((buf[1] & 1) << 1) | (buf[2] >> 7); 158cabdff1aSopenharmony_ci vert_size_ext = (buf[2] >> 5) & 3; 159cabdff1aSopenharmony_ci bit_rate_ext = ((buf[2] & 0x1F)<<7) | (buf[3]>>1); 160cabdff1aSopenharmony_ci frame_rate_ext_n = (buf[5] >> 5) & 3; 161cabdff1aSopenharmony_ci frame_rate_ext_d = (buf[5] & 0x1f); 162cabdff1aSopenharmony_ci pc->progressive_sequence = buf[1] & (1 << 3); 163cabdff1aSopenharmony_ci avctx->has_b_frames= !(buf[5] >> 7); 164cabdff1aSopenharmony_ci 165cabdff1aSopenharmony_ci chroma_format = (buf[1] >> 1) & 3; 166cabdff1aSopenharmony_ci switch (chroma_format) { 167cabdff1aSopenharmony_ci case 1: pix_fmt = AV_PIX_FMT_YUV420P; break; 168cabdff1aSopenharmony_ci case 2: pix_fmt = AV_PIX_FMT_YUV422P; break; 169cabdff1aSopenharmony_ci case 3: pix_fmt = AV_PIX_FMT_YUV444P; break; 170cabdff1aSopenharmony_ci } 171cabdff1aSopenharmony_ci 172cabdff1aSopenharmony_ci pc->width = (pc->width & 0xFFF) | (horiz_size_ext << 12); 173cabdff1aSopenharmony_ci pc->height = (pc->height& 0xFFF) | ( vert_size_ext << 12); 174cabdff1aSopenharmony_ci bit_rate = (bit_rate&0x3FFFF) | (bit_rate_ext << 18); 175cabdff1aSopenharmony_ci if(did_set_size) 176cabdff1aSopenharmony_ci set_dim_ret = ff_set_dimensions(avctx, pc->width, pc->height); 177cabdff1aSopenharmony_ci avctx->framerate.num = pc->frame_rate.num * (frame_rate_ext_n + 1); 178cabdff1aSopenharmony_ci avctx->framerate.den = pc->frame_rate.den * (frame_rate_ext_d + 1); 179cabdff1aSopenharmony_ci avctx->codec_id = AV_CODEC_ID_MPEG2VIDEO; 180cabdff1aSopenharmony_ci avctx->ticks_per_frame = 2; 181cabdff1aSopenharmony_ci } 182cabdff1aSopenharmony_ci break; 183cabdff1aSopenharmony_ci case 0x8: /* picture coding extension */ 184cabdff1aSopenharmony_ci if (bytes_left >= 5) { 185cabdff1aSopenharmony_ci top_field_first = buf[3] & (1 << 7); 186cabdff1aSopenharmony_ci repeat_first_field = buf[3] & (1 << 1); 187cabdff1aSopenharmony_ci progressive_frame = buf[4] & (1 << 7); 188cabdff1aSopenharmony_ci 189cabdff1aSopenharmony_ci /* check if we must repeat the frame */ 190cabdff1aSopenharmony_ci s->repeat_pict = 1; 191cabdff1aSopenharmony_ci if (repeat_first_field) { 192cabdff1aSopenharmony_ci if (pc->progressive_sequence) { 193cabdff1aSopenharmony_ci if (top_field_first) 194cabdff1aSopenharmony_ci s->repeat_pict = 5; 195cabdff1aSopenharmony_ci else 196cabdff1aSopenharmony_ci s->repeat_pict = 3; 197cabdff1aSopenharmony_ci } else if (progressive_frame) { 198cabdff1aSopenharmony_ci s->repeat_pict = 2; 199cabdff1aSopenharmony_ci } 200cabdff1aSopenharmony_ci } 201cabdff1aSopenharmony_ci 202cabdff1aSopenharmony_ci if (!pc->progressive_sequence && !progressive_frame) { 203cabdff1aSopenharmony_ci if (top_field_first) 204cabdff1aSopenharmony_ci s->field_order = AV_FIELD_TT; 205cabdff1aSopenharmony_ci else 206cabdff1aSopenharmony_ci s->field_order = AV_FIELD_BB; 207cabdff1aSopenharmony_ci } else 208cabdff1aSopenharmony_ci s->field_order = AV_FIELD_PROGRESSIVE; 209cabdff1aSopenharmony_ci } 210cabdff1aSopenharmony_ci break; 211cabdff1aSopenharmony_ci } 212cabdff1aSopenharmony_ci } 213cabdff1aSopenharmony_ci break; 214cabdff1aSopenharmony_ci case -1: 215cabdff1aSopenharmony_ci goto the_end; 216cabdff1aSopenharmony_ci default: 217cabdff1aSopenharmony_ci /* we stop parsing when we encounter a slice. It ensures 218cabdff1aSopenharmony_ci that this function takes a negligible amount of time */ 219cabdff1aSopenharmony_ci if (start_code >= SLICE_MIN_START_CODE && 220cabdff1aSopenharmony_ci start_code <= SLICE_MAX_START_CODE) 221cabdff1aSopenharmony_ci goto the_end; 222cabdff1aSopenharmony_ci break; 223cabdff1aSopenharmony_ci } 224cabdff1aSopenharmony_ci } 225cabdff1aSopenharmony_ci the_end: 226cabdff1aSopenharmony_ci if (set_dim_ret < 0) 227cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Failed to set dimensions\n"); 228cabdff1aSopenharmony_ci 229cabdff1aSopenharmony_ci if (avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO && bit_rate) { 230cabdff1aSopenharmony_ci avctx->rc_max_rate = 400LL*bit_rate; 231cabdff1aSopenharmony_ci } 232cabdff1aSopenharmony_ci if (bit_rate && 233cabdff1aSopenharmony_ci ((avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO && bit_rate != 0x3FFFF) || vbv_delay != 0xFFFF)) { 234cabdff1aSopenharmony_ci avctx->bit_rate = 400LL*bit_rate; 235cabdff1aSopenharmony_ci } 236cabdff1aSopenharmony_ci 237cabdff1aSopenharmony_ci if (pix_fmt != AV_PIX_FMT_NONE) { 238cabdff1aSopenharmony_ci s->format = pix_fmt; 239cabdff1aSopenharmony_ci s->width = pc->width; 240cabdff1aSopenharmony_ci s->height = pc->height; 241cabdff1aSopenharmony_ci s->coded_width = FFALIGN(pc->width, 16); 242cabdff1aSopenharmony_ci s->coded_height = FFALIGN(pc->height, 16); 243cabdff1aSopenharmony_ci } 244cabdff1aSopenharmony_ci 245cabdff1aSopenharmony_ci#if FF_API_AVCTX_TIMEBASE 246cabdff1aSopenharmony_ci if (avctx->framerate.num) 247cabdff1aSopenharmony_ci avctx->time_base = av_inv_q(av_mul_q(avctx->framerate, (AVRational){avctx->ticks_per_frame, 1})); 248cabdff1aSopenharmony_ci#endif 249cabdff1aSopenharmony_ci} 250cabdff1aSopenharmony_ci 251cabdff1aSopenharmony_cistatic int mpegvideo_parse(AVCodecParserContext *s, 252cabdff1aSopenharmony_ci AVCodecContext *avctx, 253cabdff1aSopenharmony_ci const uint8_t **poutbuf, int *poutbuf_size, 254cabdff1aSopenharmony_ci const uint8_t *buf, int buf_size) 255cabdff1aSopenharmony_ci{ 256cabdff1aSopenharmony_ci struct MpvParseContext *pc1 = s->priv_data; 257cabdff1aSopenharmony_ci ParseContext *pc= &pc1->pc; 258cabdff1aSopenharmony_ci int next; 259cabdff1aSopenharmony_ci 260cabdff1aSopenharmony_ci if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ 261cabdff1aSopenharmony_ci next= buf_size; 262cabdff1aSopenharmony_ci }else{ 263cabdff1aSopenharmony_ci#if FF_API_FLAG_TRUNCATED 264cabdff1aSopenharmony_ci next= ff_mpeg1_find_frame_end(pc, buf, buf_size, s); 265cabdff1aSopenharmony_ci#else 266cabdff1aSopenharmony_ci next = mpeg1_find_frame_end(pc, buf, buf_size, s); 267cabdff1aSopenharmony_ci#endif 268cabdff1aSopenharmony_ci 269cabdff1aSopenharmony_ci if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { 270cabdff1aSopenharmony_ci *poutbuf = NULL; 271cabdff1aSopenharmony_ci *poutbuf_size = 0; 272cabdff1aSopenharmony_ci return buf_size; 273cabdff1aSopenharmony_ci } 274cabdff1aSopenharmony_ci 275cabdff1aSopenharmony_ci } 276cabdff1aSopenharmony_ci /* we have a full frame : we just parse the first few MPEG headers 277cabdff1aSopenharmony_ci to have the full timing information. The time take by this 278cabdff1aSopenharmony_ci function should be negligible for uncorrupted streams */ 279cabdff1aSopenharmony_ci mpegvideo_extract_headers(s, avctx, buf, buf_size); 280cabdff1aSopenharmony_ci ff_dlog(NULL, "pict_type=%d frame_rate=%0.3f repeat_pict=%d\n", 281cabdff1aSopenharmony_ci s->pict_type, av_q2d(avctx->framerate), s->repeat_pict); 282cabdff1aSopenharmony_ci 283cabdff1aSopenharmony_ci *poutbuf = buf; 284cabdff1aSopenharmony_ci *poutbuf_size = buf_size; 285cabdff1aSopenharmony_ci return next; 286cabdff1aSopenharmony_ci} 287cabdff1aSopenharmony_ci 288cabdff1aSopenharmony_cistatic int mpegvideo_parse_init(AVCodecParserContext *s) 289cabdff1aSopenharmony_ci{ 290cabdff1aSopenharmony_ci s->pict_type = AV_PICTURE_TYPE_NONE; // first frame might be partial 291cabdff1aSopenharmony_ci return 0; 292cabdff1aSopenharmony_ci} 293cabdff1aSopenharmony_ci 294cabdff1aSopenharmony_ciconst AVCodecParser ff_mpegvideo_parser = { 295cabdff1aSopenharmony_ci .codec_ids = { AV_CODEC_ID_MPEG1VIDEO, AV_CODEC_ID_MPEG2VIDEO }, 296cabdff1aSopenharmony_ci .priv_data_size = sizeof(struct MpvParseContext), 297cabdff1aSopenharmony_ci .parser_init = mpegvideo_parse_init, 298cabdff1aSopenharmony_ci .parser_parse = mpegvideo_parse, 299cabdff1aSopenharmony_ci .parser_close = ff_parse_close, 300cabdff1aSopenharmony_ci}; 301