diff options
author | Baptiste Coudurier <baptiste.coudurier@gmail.com> | 2009-06-30 07:41:40 +0000 |
---|---|---|
committer | Baptiste Coudurier <baptiste.coudurier@gmail.com> | 2009-06-30 07:41:40 +0000 |
commit | 61f9e3c16a880bb2084166843dec03ee4aef73f8 (patch) | |
tree | fdad07cea318f9ad95889bab176f9a53934b8a78 /libavformat | |
parent | 470de55aa17cb933a21f7e4c4015202eaba7277f (diff) | |
download | ffmpeg-61f9e3c16a880bb2084166843dec03ee4aef73f8.tar.gz |
correctly compute frame flags with closed gop
Originally committed as revision 19304 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat')
-rw-r--r-- | libavformat/mxfenc.c | 28 |
1 files changed, 19 insertions, 9 deletions
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"); |