summaryrefslogtreecommitdiff
path: root/libavformat/mxfenc.c
diff options
context:
space:
mode:
authorBaptiste Coudurier <baptiste.coudurier@gmail.com>2009-06-30 07:41:40 +0000
committerBaptiste Coudurier <baptiste.coudurier@gmail.com>2009-06-30 07:41:40 +0000
commit61f9e3c16a880bb2084166843dec03ee4aef73f8 (patch)
treefdad07cea318f9ad95889bab176f9a53934b8a78 /libavformat/mxfenc.c
parent470de55aa17cb933a21f7e4c4015202eaba7277f (diff)
correctly compute frame flags with closed gop
Originally committed as revision 19304 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat/mxfenc.c')
-rw-r--r--libavformat/mxfenc.c28
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");