diff options
author | Baptiste Coudurier <baptiste.coudurier@gmail.com> | 2009-01-31 06:32:12 +0000 |
---|---|---|
committer | Baptiste Coudurier <baptiste.coudurier@gmail.com> | 2009-01-31 06:32:12 +0000 |
commit | 7c7c1a76db08d3b91ac630c284b040cacc624039 (patch) | |
tree | 4b6bd8ca9ccadba41c7b8a1818cae280607407b7 /libavformat/mxfenc.c | |
parent | cc812c8c7e45e11df1ac825e03b2910df55198f7 (diff) | |
download | ffmpeg-7c7c1a76db08d3b91ac630c284b040cacc624039.tar.gz |
delay header writing and parse mpeg2 frame
Originally committed as revision 16888 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat/mxfenc.c')
-rw-r--r-- | libavformat/mxfenc.c | 50 |
1 files changed, 34 insertions, 16 deletions
diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c index 3dcae36930..3bec8df772 100644 --- a/libavformat/mxfenc.c +++ b/libavformat/mxfenc.c @@ -91,6 +91,7 @@ typedef struct MXFContext { int essence_container_count; uint8_t essence_containers_indices[FF_ARRAY_ELEMS(mxf_essence_container_uls)]; AVRational time_base; + int header_written; } MXFContext; static const uint8_t uuid_base[] = { 0xAD,0xAB,0x44,0x24,0x2f,0x25,0x4d,0xc7,0x92,0xff,0x29,0xbd }; @@ -797,6 +798,26 @@ static const UID *mxf_get_mpeg2_codec_ul(AVCodecContext *avctx) return NULL; } +static int mxf_parse_mpeg2_frame(AVFormatContext *s, AVStream *st, AVPacket *pkt) +{ + MXFStreamContext *sc = st->priv_data; + uint32_t c = -1; + int i; + + for(i = 0; i < pkt->size - 4; i++) { + c = (c<<8) + pkt->data[i]; + if (c == 0x1B5) { + if (i + 2 < pkt->size && (pkt->data[i+1] & 0xf0) == 0x10) { // seq ext + st->codec->profile = pkt->data[i+1] & 0x07; + st->codec->level = pkt->data[i+2] >> 4; + break; + } + } + } + sc->codec_ul = mxf_get_mpeg2_codec_ul(st->codec); + return !!sc->codec_ul; +} + static int ff_audio_interleave_init(AVFormatContext *s, const int *samples_per_frame) { int i; @@ -865,20 +886,7 @@ static int mxf_write_header(AVFormatContext *s) return -1; } - if (st->codec->codec_id == CODEC_ID_MPEG2VIDEO) { - if (st->codec->profile == FF_PROFILE_UNKNOWN || - st->codec->level == FF_LEVEL_UNKNOWN) { - av_log(s, AV_LOG_ERROR, "track %d: profile and level must be set for mpeg-2\n", i); - return -1; - } - sc->codec_ul = mxf_get_mpeg2_codec_ul(st->codec); - if (!sc->codec_ul) { - av_log(s, AV_LOG_ERROR, "track %d: could not find codec ul for mpeg-2, " - "unsupported profile/level\n", i); - return -1; - } - } else - sc->codec_ul = &mxf_essence_container_uls[sc->index].codec_ul; + sc->codec_ul = &mxf_essence_container_uls[sc->index].codec_ul; if (!present[sc->index]) { mxf->essence_containers_indices[mxf->essence_container_count++] = sc->index; @@ -901,17 +909,27 @@ static int mxf_write_header(AVFormatContext *s) if (ff_audio_interleave_init(s, samples_per_frame) < 0) return -1; - mxf_write_partition(s, 1, header_open_partition_key, 1); - return 0; } static int mxf_write_packet(AVFormatContext *s, AVPacket *pkt) { + MXFContext *mxf = s->priv_data; ByteIOContext *pb = s->pb; AVStream *st = s->streams[pkt->stream_index]; MXFStreamContext *sc = st->priv_data; + if (!mxf->header_written) { + if (st->codec->codec_id == CODEC_ID_MPEG2VIDEO) { + if (!mxf_parse_mpeg2_frame(s, st, pkt)) { + av_log(s, AV_LOG_ERROR, "could not get mpeg2 profile and level\n"); + return -1; + } + } + mxf_write_partition(s, 1, header_open_partition_key, 1); + mxf->header_written = 1; + } + put_buffer(pb, sc->track_essence_element_key, 16); // write key klv_encode_ber_length(pb, pkt->size); // write length put_buffer(pb, pkt->data, pkt->size); // write value |