The 'fiel' atoms can be found in H.264 tracks clobbering the extradata. MJPEG supports non field based extradata, and this data should be preserved when copying.tags/n0.10
| @@ -2070,6 +2070,7 @@ static int transcode_init(OutputFile *output_files, | |||
| codec->bit_rate = icodec->bit_rate; | |||
| codec->rc_max_rate = icodec->rc_max_rate; | |||
| codec->rc_buffer_size = icodec->rc_buffer_size; | |||
| codec->field_order = icodec->field_order; | |||
| codec->extradata = av_mallocz(extra_size); | |||
| if (!codec->extradata) { | |||
| return AVERROR(ENOMEM); | |||
| @@ -1262,6 +1262,15 @@ typedef struct AVFrame { | |||
| struct AVCodecInternal; | |||
| enum AVFieldOrder { | |||
| AV_FIELD_UNKNOWN, | |||
| AV_FIELD_PROGRESSIVE, | |||
| AV_FIELD_TT, //< Top coded_first, top displayed first | |||
| AV_FIELD_BB, //< Bottom coded first, bottom displayed first | |||
| AV_FIELD_TB, //< Top coded first, bottom displayed first | |||
| AV_FIELD_BT, //< Bottom coded first, top displayed first | |||
| }; | |||
| /** | |||
| * main external API structure. | |||
| * New fields can be added to the end with minor version bumps. | |||
| @@ -3108,6 +3117,12 @@ typedef struct AVCodecContext { | |||
| * libavcodec functions. | |||
| */ | |||
| struct AVCodecInternal *internal; | |||
| /** Field order | |||
| * - encoding: set by libavcodec | |||
| * - decoding: Set by libavcodec | |||
| */ | |||
| enum AVFieldOrder field_order; | |||
| } AVCodecContext; | |||
| /** | |||
| @@ -110,12 +110,9 @@ av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx) | |||
| return AVERROR_INVALIDDATA; | |||
| } | |||
| } | |||
| if (avctx->extradata_size > 9 && | |||
| AV_RL32(avctx->extradata + 4) == MKTAG('f','i','e','l')) { | |||
| if (avctx->extradata[9] == 6) { /* quicktime icefloe 019 */ | |||
| s->interlace_polarity = 1; /* bottom field first */ | |||
| av_log(avctx, AV_LOG_DEBUG, "mjpeg bottom field first\n"); | |||
| } | |||
| if (avctx->field_order == AV_FIELD_BB) { /* quicktime icefloe 019 */ | |||
| s->interlace_polarity = 1; /* bottom field first */ | |||
| av_log(avctx, AV_LOG_DEBUG, "mjpeg bottom field first\n"); | |||
| } | |||
| if (avctx->codec->id == CODEC_ID_AMV) | |||
| s->flipped = 1; | |||
| @@ -841,6 +841,40 @@ static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom) | |||
| return 0; | |||
| } | |||
| static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom) | |||
| { | |||
| AVStream *st; | |||
| unsigned mov_field_order; | |||
| enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN; | |||
| if (c->fc->nb_streams < 1) // will happen with jp2 files | |||
| return 0; | |||
| st = c->fc->streams[c->fc->nb_streams-1]; | |||
| if (atom.size < 2) | |||
| return AVERROR_INVALIDDATA; | |||
| mov_field_order = avio_rb16(pb); | |||
| if ((mov_field_order & 0xFF00) == 0x0100) | |||
| decoded_field_order = AV_FIELD_PROGRESSIVE; | |||
| else if ((mov_field_order & 0xFF00) == 0x0200) { | |||
| switch (mov_field_order & 0xFF) { | |||
| case 0x01: decoded_field_order = AV_FIELD_TT; | |||
| break; | |||
| case 0x06: decoded_field_order = AV_FIELD_BB; | |||
| break; | |||
| case 0x09: decoded_field_order = AV_FIELD_TB; | |||
| break; | |||
| case 0x0E: decoded_field_order = AV_FIELD_BT; | |||
| break; | |||
| } | |||
| } | |||
| if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) { | |||
| av_log(NULL, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order); | |||
| } | |||
| st->codec->field_order = decoded_field_order; | |||
| return 0; | |||
| } | |||
| /* FIXME modify qdm2/svq3/h264 decoders to take full atom as extradata */ | |||
| static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom) | |||
| { | |||
| @@ -908,6 +942,15 @@ static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom) | |||
| if ((uint64_t)atom.size > (1<<30)) | |||
| return -1; | |||
| if (atom.size >= 10) { | |||
| // Broken files created by legacy versions of Libav and FFmpeg will | |||
| // wrap a whole fiel atom inside of a glbl atom. | |||
| unsigned size = avio_rb32(pb); | |||
| unsigned type = avio_rl32(pb); | |||
| avio_seek(pb, -8, SEEK_CUR); | |||
| if (type == MKTAG('f','i','e','l') && size == atom.size) | |||
| return mov_read_default(c, pb, atom); | |||
| } | |||
| av_free(st->codec->extradata); | |||
| st->codec->extradata = av_mallocz(atom.size + FF_INPUT_BUFFER_PADDING_SIZE); | |||
| if (!st->codec->extradata) | |||
| @@ -2331,7 +2374,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = { | |||
| { MKTAG('e','d','t','s'), mov_read_default }, | |||
| { MKTAG('e','l','s','t'), mov_read_elst }, | |||
| { MKTAG('e','n','d','a'), mov_read_enda }, | |||
| { MKTAG('f','i','e','l'), mov_read_extradata }, | |||
| { MKTAG('f','i','e','l'), mov_read_fiel }, | |||
| { MKTAG('f','t','y','p'), mov_read_ftyp }, | |||
| { MKTAG('g','l','b','l'), mov_read_glbl }, | |||
| { MKTAG('h','d','l','r'), mov_read_hdlr }, | |||
| @@ -783,6 +783,23 @@ static int mov_write_uuid_tag_ipod(AVIOContext *pb) | |||
| return 28; | |||
| } | |||
| static const uint16_t fiel_data[] = { | |||
| 0x0000, 0x0100, 0x0201, 0x0206, 0x0209, 0x020e | |||
| }; | |||
| static int mov_write_fiel_tag(AVIOContext *pb, MOVTrack *track) | |||
| { | |||
| unsigned mov_field_order = 0; | |||
| if (track->enc->field_order < FF_ARRAY_ELEMS(fiel_data)) | |||
| mov_field_order = fiel_data[track->enc->field_order]; | |||
| else | |||
| return 0; | |||
| avio_wb32(pb, 10); | |||
| ffio_wfourcc(pb, "fiel"); | |||
| avio_wb16(pb, mov_field_order); | |||
| return 10; | |||
| } | |||
| static int mov_write_subtitle_tag(AVIOContext *pb, MOVTrack *track) | |||
| { | |||
| int64_t pos = avio_tell(pb); | |||
| @@ -869,7 +886,9 @@ static int mov_write_video_tag(AVIOContext *pb, MOVTrack *track) | |||
| mov_write_avcc_tag(pb, track); | |||
| if(track->mode == MODE_IPOD) | |||
| mov_write_uuid_tag_ipod(pb); | |||
| } else if(track->vosLen > 0) | |||
| } else if (track->enc->field_order != AV_FIELD_UNKNOWN) | |||
| mov_write_fiel_tag(pb, track); | |||
| else if(track->vosLen > 0) | |||
| mov_write_glbl_tag(pb, track); | |||
| if (track->enc->sample_aspect_ratio.den && track->enc->sample_aspect_ratio.num && | |||