[FFmpeg-devel] Gaining access to a encoder context in avformat?

Kevin Wheatley kevin.j.wheatley at gmail.com
Fri Feb 20 14:48:55 CET 2015


Here is the kind of thing that this looks like... This is definitely
NOT a patch :-)

On Fri, Feb 20, 2015 at 1:22 PM, Michael Niedermayer <michaelni at gmx.at> wrote:
> On Fri, Feb 20, 2015 at 12:35:59PM +0000, Kevin Wheatley wrote:
>> Please excuse my newbie knowledge of the code base BTW...
>>
>> I've just done a simple test
>>
>> ffmpeg -color_range mpeg -i test_charts/test_encoding.tif -c dnxhd -vb
>> 115M  /quicktimes/ffmpeg_test.mov
>>
>> During this the vos_data contains...
>>
>> 00 00 02 80 01 01 80 A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> 00 04 38 07 80 00 04 38 00 00 38 88 ...
>>
>> Which looks to me like the start of the VC3/DNxHD bit stream and in
>> this case the code puts valid data in the header atoms.
>>
>> If I then
>>
>> fmpeg -i quicktimes/ffmpeg_test.mov -c copy quicktimes/ffmpeg_test_copy.mov
>>
>> the vos_data instead contains
>>
>> 00 00 00 18 41 43 4C 52 41 43 4C 52 30 30 30 31 00 00 00 01 00 00 00
>> 00 00 00 00 18 41 50 52 47 41 50 52 47 ...
>>
>> which is the  start of the Avid atoms from the incomming Quicktime.
>>
>> So I could peak into the stream and 'guess' based on the content being
>> 0x00, 0x00, 0x02, 0x80, 0x01  that we are encoding and can trust the
>> contents, else I could search through looking for the atom via the
>> string "ARESARES" and then having located it I could assume to use
>> that. The only oddball case is if it is not found, at that point the
>> code needs to know if it is interlaced as well as the avid codec
>> identifier, or maybe that is the point at which we 'give up' and fail
>> with unsupported?
>
> if you need to put 2 bits from a fixed location of the "first" packet
> into some avid atoms its probably easiest to read them straight out of
> the first packet into some new field in a struct and then use that
> when writing the atoms.
>
> IIUC theres no generic field in AVStream, AVCodecContext or elsewhere
> that holds this information. If there is, setting this field from the
> encoder/demuxer and using it would be the more correct path
>
> extracting the data from vos_data seems trickier
>
> It would also be possible to add a first_packet field where vos_data
> is and always initialize it to the first packet and use that instead
>
> I sure do not fully know all the details of the issue so i might be
> missing something
>
> [...]
>
> --
> Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
>
> There will always be a question for which you do not know the correct answer.
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
-------------- next part --------------
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index a72f84e..dc5a7b4 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -1033,6 +1033,10 @@ static int mov_write_hvcc_tag(AVIOContext *pb, MOVTrack *track)
 static int mov_write_avid_tag(AVIOContext *pb, MOVTrack *track)
 {
     int i;
+    int interlaced = 0;
+    int cid = 0;
+    uint32_t temp;
+    
     avio_wb32(pb, 24); /* size */
     ffio_wfourcc(pb, "ACLR");
     ffio_wfourcc(pb, "ACLR");
@@ -1056,10 +1060,43 @@ static int mov_write_avid_tag(AVIOContext *pb, MOVTrack *track)
     ffio_wfourcc(pb, "ARES");
     ffio_wfourcc(pb, "ARES");
     ffio_wfourcc(pb, "0001");
-    avio_wb32(pb, AV_RB32(track->vos_data + 0x28)); /* dnxhd cid, some id ? */
+    
+    if (track->vos_data && track->vos_len > 0x29) { 
+        if (track->vos_data[0] == 0x00 &&
+            track->vos_data[1] == 0x00 &&
+            track->vos_data[2] == 0x02 &&
+            track->vos_data[3] == 0x80 &&
+            (track->vos_data[4] == 0x01 ||track->vos_data[4] == 0x02)) {
+            /* looks like a DNxHD bit stream */
+            interlaced = (track->vos_data[5] & 2);
+            cid = AV_RB32(track->vos_data + 0x28);
+        } else if (track->vos_len > 120) { /* big enough to contain the atom */
+            for (i = 0; i < (track->vos_len - 4); i += 4) {
+                temp = AV_RL32(track->vos_data + i);
+                if ((AV_RL32(track->vos_data + i) == MKTAG('A', 'R', 'E', 'S')) &&
+                    (AV_RL32(track->vos_data + i + 4) == MKTAG('A', 'R', 'E', 'S')))
+                    break;
+            }
+            if (i < (track->vos_len - 12))
+            {
+                interlaced = track->enc->field_order > AV_FIELD_PROGRESSIVE;
+                cid = AV_RB32(track->vos_data + i + 12);
+            } else {
+                // couldn't find it in the buffer
+                printf("couldn't find it\n");
+            }
+        }
+    } else {
+      printf("buffer too small\n");
+      // log some error not enough buffer to contain the info?
+      // return non 0?
+    }
+    
+
+    avio_wb32(pb, cid); /* dnxhd cid, some id ? */
     avio_wb32(pb, track->enc->width);
     /* values below are based on samples created with quicktime and avid codecs */
-    if (track->vos_data[5] & 2) { // interlaced
+    if (interlaced) {
         avio_wb32(pb, track->enc->height / 2);
         avio_wb32(pb, 2); /* unknown */
         avio_wb32(pb, 0); /* unknown */


More information about the ffmpeg-devel mailing list