]> granicus.if.org Git - handbrake/commitdiff
hb_ff_set_sample_fmt() improvements.
authorRodeo <tdskywalker@gmail.com>
Wed, 17 Oct 2012 22:37:34 +0000 (22:37 +0000)
committerRodeo <tdskywalker@gmail.com>
Wed, 17 Oct 2012 22:37:34 +0000 (22:37 +0000)
- allow setting a sample_fmt other than AV_SAMPLE_FMT_FLT

- fall back on planar/packed variant of the requested format if available

git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@5019 b64f7644-9d1e-0410-96f1-a4d463321fa5

libhb/decavcodec.c
libhb/encavcodecaudio.c
libhb/hb.c
libhb/hbffmpeg.h
libhb/sync.c

index 984b1cf8782c001ce1868c063e9e8161e8d4d746..4fd22c833fa16576e6cbe26386d8a9604fd20d63 100644 (file)
@@ -205,14 +205,14 @@ static int decavcodecaInit( hb_work_object_t * w, hb_job_t * job )
         AVFormatContext *ic = (AVFormatContext*)pv->title->opaque_priv;
         pv->context = avcodec_alloc_context3(codec);
         avcodec_copy_context( pv->context, ic->streams[w->audio->id]->codec);
-        hb_ff_set_sample_fmt( pv->context, codec );
+        hb_ff_set_sample_fmt( pv->context, codec, AV_SAMPLE_FMT_FLT );
     }
     else
     {
         pv->parser = av_parser_init( w->codec_param );
 
         pv->context = avcodec_alloc_context3(codec);
-        hb_ff_set_sample_fmt( pv->context, codec );
+        hb_ff_set_sample_fmt( pv->context, codec, AV_SAMPLE_FMT_FLT );
     }
     if ( hb_avcodec_open( pv->context, codec, NULL, 0 ) )
     {
@@ -393,7 +393,7 @@ static int decavcodecaBSInfo( hb_work_object_t *w, const hb_buffer_t *buf,
 
     AVCodecParserContext *parser = av_parser_init( codec->id );
     AVCodecContext *context = avcodec_alloc_context3(codec);
-    hb_ff_set_sample_fmt( context, codec );
+    hb_ff_set_sample_fmt( context, codec, AV_SAMPLE_FMT_FLT );
     if ( hb_avcodec_open( context, codec, NULL, 0 ) )
     {
         return -1;
index fe398ab4fe0c44ab13312634001ae9f4dd331928..0fc23faa0ee4b028249a14fe3b23f1de066e2326 100644 (file)
@@ -89,8 +89,15 @@ static int encavcodecaInit(hb_work_object_t *w, hb_job_t *job)
         context->compression_level = audio->config.out.compression_level;
     }
 
-    // Try to set format to float; fall back to whatever is supported.
-    hb_ff_set_sample_fmt(context, codec);
+    // set the sample_fmt to something practical
+    if (audio->config.out.codec == HB_ACODEC_FFFLAC)
+    {
+        hb_ff_set_sample_fmt(context, codec, AV_SAMPLE_FMT_S16);
+    }
+    else
+    {
+        hb_ff_set_sample_fmt(context, codec, AV_SAMPLE_FMT_FLT);
+    }
 
     if (hb_avcodec_open(context, codec, &av_opts, 0))
     {
index 12377a8b584cdd1fd576a14761d0dc057cbb2384..52ddc206b94e0b520db1815438d46709bd4b1038 100644 (file)
@@ -285,30 +285,47 @@ uint64_t hb_ff_layout_xlat(uint64_t ff_channel_layout, int nchannels)
     return hb_layout;
 }
 
-// Set sample format to AV_SAMPLE_FMT_FLT if supported.
-// If it is not supported, we will have to translate using
-// av_audio_convert.
-void hb_ff_set_sample_fmt(AVCodecContext *context, AVCodec *codec)
+/*
+ * Set sample format to the request format if supported by the codec.
+ * The planar/packed variant of the requested format is the next best thing.
+ */
+void hb_ff_set_sample_fmt(AVCodecContext *context, AVCodec *codec,
+                          enum AVSampleFormat request_sample_fmt)
 {
-    if ( codec && codec->sample_fmts )
+    if (context != NULL && codec != NULL &&
+        codec->type == AVMEDIA_TYPE_AUDIO && codec->sample_fmts != NULL)
     {
-        if ( codec->type != AVMEDIA_TYPE_AUDIO )
-            return; // Not audio
-
         const enum AVSampleFormat *fmt;
+        enum AVSampleFormat next_best_fmt;
+
+        next_best_fmt = (av_sample_fmt_is_planar(request_sample_fmt)  ?
+                         av_get_packed_sample_fmt(request_sample_fmt) :
+                         av_get_planar_sample_fmt(request_sample_fmt));
 
-        for ( fmt = codec->sample_fmts; *fmt != -1; fmt++ )
+        context->request_sample_fmt = AV_SAMPLE_FMT_NONE;
+
+        for (fmt = codec->sample_fmts; *fmt != AV_SAMPLE_FMT_NONE; fmt++)
         {
-            if ( *fmt == AV_SAMPLE_FMT_FLT )
+            if (*fmt == request_sample_fmt)
             {
-                context->request_sample_fmt = AV_SAMPLE_FMT_FLT;
-                context->sample_fmt = AV_SAMPLE_FMT_FLT;
+                context->request_sample_fmt = request_sample_fmt;
                 break;
             }
+            else if (*fmt == next_best_fmt)
+            {
+                context->request_sample_fmt = next_best_fmt;
+            }
         }
-        if ( *fmt == -1 )
-            context->sample_fmt = codec->sample_fmts[0];
 
+        /*
+         * When encoding and AVCodec.sample_fmts exists, avcodec_open2()
+         * will error out if AVCodecContext.sample_fmt isn't set.
+         */
+        if (context->request_sample_fmt == AV_SAMPLE_FMT_NONE)
+        {
+            context->request_sample_fmt = codec->sample_fmts[0];
+        }
+        context->sample_fmt = context->request_sample_fmt;
     }
 }
 
index 51b51d8af9af2ca7a03e87335354f5488257d0e3..2de77150516f0ecff0c9cc390c72092057d3acb8 100644 (file)
@@ -24,7 +24,7 @@ int  hb_avcodec_close(AVCodecContext *);
 
 uint64_t hb_ff_layout_xlat(uint64_t ff_channel_layout, int nchannels);
 uint64_t hb_ff_mixdown_xlat(int hb_mixdown, int *downmix_mode);
-void     hb_ff_set_sample_fmt(AVCodecContext *context, AVCodec *codec);
+void     hb_ff_set_sample_fmt(AVCodecContext *, AVCodec *, enum AVSampleFormat);
 
 struct SwsContext*
 hb_sws_get_context(int srcW, int srcH, enum PixelFormat srcFormat,
index cd45b7fdddf882ac1938752a83a7495adfd4c3ad..c3e4c37a187f5ee717495579e9d98ae3ca959f83 100644 (file)
@@ -946,12 +946,12 @@ static void InitAudio( hb_job_t * job, hb_sync_common_t * common, int i )
             } break;
         }
 
-        c     = avcodec_alloc_context3( codec );
-
+        c              = avcodec_alloc_context3(codec);
         c->bit_rate    = w->audio->config.in.bitrate;
         c->sample_rate = w->audio->config.in.samplerate;
-        c->channels    = av_get_channel_layout_nb_channels(w->audio->config.in.channel_layout);
-        hb_ff_set_sample_fmt( c, codec );
+        c->channels    =
+            av_get_channel_layout_nb_channels(w->audio->config.in.channel_layout);
+        hb_ff_set_sample_fmt(c, codec, AV_SAMPLE_FMT_FLT);
 
         if (w->audio->config.in.channel_layout == AV_CH_LAYOUT_STEREO_DOWNMIX)
         {