]> git.sesse.net Git - ffmpeg/commitdiff
Handle r10k endianess atom DpxE.
authorCarl Eugen Hoyos <cehoyos@ag.or.at>
Sun, 11 Jan 2015 11:11:36 +0000 (12:11 +0100)
committerCarl Eugen Hoyos <cehoyos@ag.or.at>
Sun, 11 Jan 2015 11:15:03 +0000 (12:15 +0100)
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
libavformat/mov.c
libavformat/movenc.c

index a2e1a070e1186a510cb7c094c0204198496893a7..fc9e7e5ce5893a4a3dcfe48c31516e9b722121cc 100644 (file)
@@ -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++);
index 19ec11f9684aea8fb7cc9ee8ea68964df8fe5e84..3dee57203898a1f3fe9d46e844ee4cbb45e57841 100644 (file)
@@ -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 },
index bc2d9eff2b4c098e887bdf261b3c734b031a50ca..29535cdaebff180ce0cd77783096b94b122b7050 100644 (file)
@@ -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);