From a5334d408148f20e0680f65daa3aff837c5f5db5 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Sun, 11 Jan 2015 12:11:36 +0100 Subject: [PATCH] Handle r10k endianess atom DpxE. Fixes playback and remuxing of r10k_full-range_big-endian.mov. Reported, analyzed and tested by Olaf Matthes, olaf matthes gmx de --- libavcodec/r210dec.c | 5 ++++- libavformat/mov.c | 6 ++++++ libavformat/movenc.c | 16 ++++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/libavcodec/r210dec.c b/libavcodec/r210dec.c index a2e1a070e1..fc9e7e5ce5 100644 --- a/libavcodec/r210dec.c +++ b/libavcodec/r210dec.c @@ -47,6 +47,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, avctx->codec_id == AV_CODEC_ID_R10K ? 1 : 64); uint8_t *dst_line; int r10 = (avctx->codec_tag & 0xFFFFFF) == MKTAG('r', '1', '0', 0); + int le = avctx->codec_tag == MKTAG('R', '1', '0', 'k') && + avctx->extradata_size >= 12 && !memcmp(&avctx->extradata[4], "DpxE", 4) && + !avctx->extradata[11]; if (avpkt->size < 4 * aligned_width * avctx->height) { av_log(avctx, AV_LOG_ERROR, "packet too small\n"); @@ -65,7 +68,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, for (w = 0; w < avctx->width; w++) { uint32_t pixel; uint16_t r, g, b; - if (avctx->codec_id == AV_CODEC_ID_AVRP || r10) { + if (avctx->codec_id == AV_CODEC_ID_AVRP || r10 || le) { pixel = av_le2ne32(*src++); } else { pixel = av_be2ne32(*src++); diff --git a/libavformat/mov.c b/libavformat/mov.c index 19ec11f968..3dee572038 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1114,6 +1114,11 @@ static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom) return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000); } +static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom) +{ + return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K); +} + static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom) { int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI); @@ -3363,6 +3368,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = { { MKTAG('c','o','l','r'), mov_read_colr }, { MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */ { MKTAG('d','i','n','f'), mov_read_default }, +{ MKTAG('D','p','x','E'), mov_read_dpxe }, { MKTAG('d','r','e','f'), mov_read_dref }, { MKTAG('e','d','t','s'), mov_read_default }, { MKTAG('e','l','s','t'), mov_read_elst }, diff --git a/libavformat/movenc.c b/libavformat/movenc.c index bc2d9eff2b..29535cdaeb 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -1081,6 +1081,19 @@ static int mov_write_avid_tag(AVIOContext *pb, MOVTrack *track) return 0; } +static int mov_write_dpxe_tag(AVIOContext *pb, MOVTrack *track) +{ + avio_wb32(pb, 12); + ffio_wfourcc(pb, "DpxE"); + if (track->enc->extradata_size >= 12 && + !memcmp(&track->enc->extradata[4], "DpxE", 4)) { + avio_wb32(pb, track->enc->extradata[11]); + } else { + avio_wb32(pb, 1); + } + return 0; +} + static int mp4_get_codec_tag(AVFormatContext *s, MOVTrack *track) { int tag = track->enc->codec_tag; @@ -1580,6 +1593,9 @@ static int mov_write_video_tag(AVIOContext *pb, MOVTrack *track) track->enc->codec_id == AV_CODEC_ID_VP6A) { /* Don't write any potential extradata here - the cropping * is signalled via the normal width/height fields. */ + } else if (track->enc->codec_id == AV_CODEC_ID_R10K) { + if (track->enc->codec_tag == MKTAG('R','1','0','k')) + mov_write_dpxe_tag(pb, track); } else if (track->vos_len > 0) mov_write_glbl_tag(pb, track);