[FFmpeg-devel] [PATCH 2/4] ffmpeg: use the write_uncoded_frame() API.

Nicolas George george at nsup.org
Wed Jan 1 13:27:06 CET 2014


Signed-off-by: Nicolas George <george at nsup.org>
---
 ffmpeg.c |   48 +++++++++++++++++++++++++++++++++++++++++-------
 ffmpeg.h |    1 +
 2 files changed, 42 insertions(+), 7 deletions(-)

diff --git a/ffmpeg.c b/ffmpeg.c
index 5ccbf10..bfb84d3 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -644,7 +644,15 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost)
               );
     }
 
-    ret = av_interleaved_write_frame(s, pkt);
+    if (ost->uncoded_frame) {
+        av_assert0(pkt->size == sizeof(AVFrame));
+        ret = av_write_uncoded_frame(s, pkt->stream_index,
+                                     (AVFrame *)pkt->data, 0);
+        pkt->size = 0;
+        pkt->data = NULL;
+    } else {
+        ret = av_interleaved_write_frame(s, pkt);
+    }
     if (ret < 0) {
         print_error("av_interleaved_write_frame()", ret);
         exit_program(1);
@@ -693,6 +701,8 @@ static void do_audio_out(AVFormatContext *s, OutputStream *ost,
         frame->pts = ost->sync_opts;
     ost->sync_opts = frame->pts + frame->nb_samples;
 
+    if (ost->encoding_needed) {
+        /* TODO reindent */
     av_assert0(pkt.size || !pkt.data);
     update_benchmark(NULL);
     if (avcodec_encode_audio2(enc, &pkt, frame, &got_packet) < 0) {
@@ -700,6 +710,13 @@ static void do_audio_out(AVFormatContext *s, OutputStream *ost,
         exit_program(1);
     }
     update_benchmark("encode_audio %d.%d", ost->file_index, ost->index);
+    } else {
+        av_assert0(ost->uncoded_frame);
+        pkt.pts = pkt.dts = frame->pts;
+        pkt.data = (void *)frame;
+        pkt.size = sizeof(*frame); /* used only for consistency checks */
+        got_packet = 1;
+    }
 
     if (got_packet) {
         if (pkt.pts != AV_NOPTS_VALUE)
@@ -968,6 +985,8 @@ static void do_video_out(AVFormatContext *s,
             av_log(NULL, AV_LOG_DEBUG, "Forced keyframe at time %f\n", pts_time);
         }
 
+        if (ost->encoding_needed) {
+            /* TODO reindent */
         update_benchmark(NULL);
         ret = avcodec_encode_video2(enc, &pkt, in_picture, &got_packet);
         update_benchmark("encode_video %d.%d", ost->file_index, ost->index);
@@ -975,6 +994,13 @@ static void do_video_out(AVFormatContext *s,
             av_log(NULL, AV_LOG_FATAL, "Video encoding failed\n");
             exit_program(1);
         }
+        } else {
+            av_assert0(ost->uncoded_frame);
+            pkt.pts = pkt.dts = in_picture->pts;
+            pkt.data = (void *)in_picture;
+            pkt.size = sizeof(*in_picture); /* used only for consistency checks */
+            got_packet = 1;
+        }
 
         if (got_packet) {
             if (pkt.pts == AV_NOPTS_VALUE && !(enc->codec->capabilities & CODEC_CAP_DELAY))
@@ -1117,7 +1143,8 @@ static int reap_filters(void)
                 break;
             case AVMEDIA_TYPE_AUDIO:
                 filtered_frame->pts = frame_pts;
-                if (!(ost->st->codec->codec->capabilities & CODEC_CAP_PARAM_CHANGE) &&
+                if (!(ost->st->codec->codec &&
+                      (ost->st->codec->codec->capabilities & CODEC_CAP_PARAM_CHANGE)) &&
                     ost->st->codec->channels != av_frame_get_channels(filtered_frame)) {
                     av_log(NULL, AV_LOG_ERROR,
                            "Audio filter graph output is not normalized and encoder does not support parameter changes\n");
@@ -2411,6 +2438,10 @@ static int transcode_init(void)
                 abort();
             }
         } else {
+            ret = av_write_uncoded_frame(oc, ost->index, NULL,
+                                         AV_WRITE_UNCODED_FRAME_QUERY);
+            if (ret < 0) {
+                /* TODO reindent */
             if (!ost->enc)
                 ost->enc = avcodec_find_encoder(codec->codec_id);
             if (!ost->enc) {
@@ -2420,10 +2451,15 @@ static int transcode_init(void)
                 ret = AVERROR(EINVAL);
                 goto dump_format;
             }
+                ost->encoding_needed = 1;
+            } else {
+                av_log(oc, AV_LOG_VERBOSE, "Using uncoded frame output "
+                       "for stream #%d\n", ost->index);
+                ost->uncoded_frame = 1;
+            }
 
             if (ist)
                 ist->decoding_needed++;
-            ost->encoding_needed = 1;
 
             if (!ost->filter &&
                 (codec->codec_type == AVMEDIA_TYPE_VIDEO ||
@@ -3400,10 +3436,8 @@ static int transcode(void)
     /* close each encoder */
     for (i = 0; i < nb_output_streams; i++) {
         ost = output_streams[i];
-        if (ost->encoding_needed) {
-            av_freep(&ost->st->codec->stats_in);
-            avcodec_close(ost->st->codec);
-        }
+        av_freep(&ost->st->codec->stats_in);
+        avcodec_close(ost->st->codec);
     }
 
     /* close each decoder */
diff --git a/ffmpeg.h b/ffmpeg.h
index 433baf8..55d7235 100644
--- a/ffmpeg.h
+++ b/ffmpeg.h
@@ -350,6 +350,7 @@ typedef struct OutputStream {
     int source_index;        /* InputStream index */
     AVStream *st;            /* stream in the output file */
     int encoding_needed;     /* true if encoding needed for this stream */
+    int uncoded_frame;       /* true if using the uncoded frame API */
     int frame_number;
     /* input pts and corresponding output pts
        for A/V sync */
-- 
1.7.10.4



More information about the ffmpeg-devel mailing list