From 61f9e3c16a880bb2084166843dec03ee4aef73f8 Mon Sep 17 00:00:00 2001 From: Baptiste Coudurier Date: Tue, 30 Jun 2009 07:41:40 +0000 Subject: correctly compute frame flags with closed gop Originally committed as revision 19304 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavformat/mxfenc.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'libavformat/mxfenc.c') diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c index 9abcab013e..ba67a8ba54 100644 --- a/libavformat/mxfenc.c +++ b/libavformat/mxfenc.c @@ -69,6 +69,7 @@ typedef struct { int interlaced; ///< wether picture is interlaced int temporal_reordering; AVRational aspect_ratio; ///< display aspect ratio + int closed_gop; ///< gop is closed, used in mpeg-2 frame parsing } MXFStreamContext; typedef struct { @@ -1111,8 +1112,8 @@ static void mxf_write_index_table_segment(AVFormatContext *s) put_be32(pb, mxf->edit_units_count); // num of entries put_be32(pb, 11+mxf->slice_count*4); // size of one entry for (i = 0; i < mxf->edit_units_count; i++) { + int temporal_offset = 0; if (temporal_reordering) { - int temporal_offset = 0; for (j = i+1; j < mxf->edit_units_count; j++) { temporal_offset++; if (mxf->index_entries[j].flags & 0x10) { // backward prediction @@ -1126,15 +1127,17 @@ static void mxf_write_index_table_segment(AVFormatContext *s) break; } } - put_byte(pb, temporal_offset); - } else - put_byte(pb, 0); + } + put_byte(pb, temporal_offset); + if (!(mxf->index_entries[i].flags & 0x33)) { // I frame + if (mxf->index_entries[i].flags & 0x40 && // seq header + (!temporal_reordering || !temporal_offset)) + mxf->index_entries[i].flags |= 0x80; // random access mxf->last_key_index = key_index; key_index = i; } - if (mxf->index_entries[i].flags & 0x10 && // backward prediction - !(mxf->index_entries[key_index].flags & 0x80)) { // open gop + if ((mxf->index_entries[i].flags & 0x30) == 0x30) { // back and forward prediction put_byte(pb, mxf->last_key_index - i); } else { put_byte(pb, key_index - i); // key frame offset @@ -1315,8 +1318,11 @@ static int mxf_parse_mpeg2_frame(AVFormatContext *s, AVStream *st, AVPacket *pkt break; } } else if (c == 0x1b8) { // gop - if (pkt->data[i+4]>>6 & 0x01) // closed - *flags |= 0x80; // random access + if (pkt->data[i+4]>>6 & 0x01) { // closed + sc->closed_gop = 1; + if (*flags & 0x40) // sequence header present + *flags |= 0x80; // random access + } if (!mxf->header_written) { unsigned hours = (pkt->data[i+1]>>2) & 0x1f; unsigned minutes = ((pkt->data[i+1] & 0x03) << 4) | (pkt->data[i+2]>>4); @@ -1347,8 +1353,12 @@ static int mxf_parse_mpeg2_frame(AVFormatContext *s, AVStream *st, AVPacket *pkt if (pict_type == 2) { // P frame *flags |= 0x22; st->codec->gop_size = 1; + sc->closed_gop = 0; // reset closed gop, don't matter anymore } else if (pict_type == 3) { // B frame - *flags |= 0x33; + if (sc->closed_gop) + *flags |= 0x13; // only backward prediction + else + *flags |= 0x33; sc->temporal_reordering = -1; } else if (!pict_type) { av_log(s, AV_LOG_ERROR, "error parsing mpeg2 frame\n"); -- cgit v1.2.3