[FFmpeg-devel] avformat/aiffenc: add aiff_init()

Submitted by James Almer on May 28, 2017, 8:39 p.m.

Details

Message ID 20170528203921.2232-1-jamrial@gmail.com
State New
Headers show

Commit Message

James Almer May 28, 2017, 8:39 p.m.
Signed-off-by: James Almer <jamrial@gmail.com>
---
 libavformat/aiffenc.c | 45 +++++++++++++++++++++++++++++----------------
 1 file changed, 29 insertions(+), 16 deletions(-)

Comments

Paul B Mahol June 17, 2017, 9:43 a.m.
On 5/28/17, James Almer <jamrial@gmail.com> wrote:
> Signed-off-by: James Almer <jamrial@gmail.com>
> ---
>  libavformat/aiffenc.c | 45 +++++++++++++++++++++++++++++----------------
>  1 file changed, 29 insertions(+), 16 deletions(-)
>
> diff --git a/libavformat/aiffenc.c b/libavformat/aiffenc.c
> index fcadf149a0..1e0c5b11a0 100644
> --- a/libavformat/aiffenc.c
> +++ b/libavformat/aiffenc.c
> @@ -98,13 +98,11 @@ static void put_meta(AVFormatContext *s, const char
> *key, uint32_t id)
>      }
>  }
>
> -static int aiff_write_header(AVFormatContext *s)
> +static int aiff_init(AVFormatContext *s)
>  {
>      AIFFOutputContext *aiff = s->priv_data;
> -    AVIOContext *pb = s->pb;
>      AVCodecParameters *par;
> -    uint64_t sample_rate;
> -    int i, aifc = 0;
> +    int i;
>
>      aiff->audio_stream_idx = -1;
>      for (i = 0; i < s->nb_streams; i++) {
> @@ -126,6 +124,32 @@ static int aiff_write_header(AVFormatContext *s)
>      /* First verify if format is ok */
>      if (!par->codec_tag)
>          return -1;
> +
> +    if (!par->bits_per_coded_sample)
> +        par->bits_per_coded_sample = av_get_bits_per_sample(par->codec_id);
> +    if (!par->bits_per_coded_sample) {
> +        av_log(s, AV_LOG_ERROR, "could not compute bits per sample\n");
> +        return -1;
> +    }
> +    if (!par->block_align)
> +        par->block_align = (par->bits_per_coded_sample * par->channels) >>
> 3;
> +
> +    avpriv_set_pts_info(s->streams[aiff->audio_stream_idx], 64, 1,
> +
> s->streams[aiff->audio_stream_idx]->codecpar->sample_rate);
> +
> +    return 0;
> +}
> +
> +static int aiff_write_header(AVFormatContext *s)
> +{
> +    AIFFOutputContext *aiff = s->priv_data;
> +    AVIOContext *pb = s->pb;
> +    AVCodecParameters *par;
> +    uint64_t sample_rate;
> +    int aifc = 0;
> +
> +    par = s->streams[aiff->audio_stream_idx]->codecpar;
> +
>      if (par->codec_tag != MKTAG('N','O','N','E'))
>          aifc = 1;
>
> @@ -165,15 +189,6 @@ static int aiff_write_header(AVFormatContext *s)
>      aiff->frames = avio_tell(pb);
>      avio_wb32(pb, 0);              /* Number of frames */
>
> -    if (!par->bits_per_coded_sample)
> -        par->bits_per_coded_sample = av_get_bits_per_sample(par->codec_id);
> -    if (!par->bits_per_coded_sample) {
> -        av_log(s, AV_LOG_ERROR, "could not compute bits per sample\n");
> -        return -1;
> -    }
> -    if (!par->block_align)
> -        par->block_align = (par->bits_per_coded_sample * par->channels) >>
> 3;
> -
>      avio_wb16(pb, par->bits_per_coded_sample); /* Sample size */
>
>      sample_rate = av_double2int(par->sample_rate);
> @@ -199,9 +214,6 @@ static int aiff_write_header(AVFormatContext *s)
>      avio_wb32(pb, 0);                    /* Data offset */
>      avio_wb32(pb, 0);                    /* Block-size (block align) */
>
> -    avpriv_set_pts_info(s->streams[aiff->audio_stream_idx], 64, 1,
> -
> s->streams[aiff->audio_stream_idx]->codecpar->sample_rate);
> -
>      /* Data is starting here */
>      avio_flush(pb);
>
> @@ -327,6 +339,7 @@ AVOutputFormat ff_aiff_muxer = {
>      .priv_data_size    = sizeof(AIFFOutputContext),
>      .audio_codec       = AV_CODEC_ID_PCM_S16BE,
>      .video_codec       = AV_CODEC_ID_PNG,
> +    .init              = aiff_init,
>      .write_header      = aiff_write_header,
>      .write_packet      = aiff_write_packet,
>      .write_trailer     = aiff_write_trailer,
> --
> 2.12.1
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>

Could you explain in detail what this patch does?
James Almer June 17, 2017, 2:35 p.m.
On 6/17/2017 6:43 AM, Paul B Mahol wrote:
> On 5/28/17, James Almer <jamrial@gmail.com> wrote:
>> Signed-off-by: James Almer <jamrial@gmail.com>
>> ---
>>  libavformat/aiffenc.c | 45 +++++++++++++++++++++++++++++----------------
>>  1 file changed, 29 insertions(+), 16 deletions(-)
>>
>> diff --git a/libavformat/aiffenc.c b/libavformat/aiffenc.c
>> index fcadf149a0..1e0c5b11a0 100644
>> --- a/libavformat/aiffenc.c
>> +++ b/libavformat/aiffenc.c
>> @@ -98,13 +98,11 @@ static void put_meta(AVFormatContext *s, const char
>> *key, uint32_t id)
>>      }
>>  }
>>
>> -static int aiff_write_header(AVFormatContext *s)
>> +static int aiff_init(AVFormatContext *s)
>>  {
>>      AIFFOutputContext *aiff = s->priv_data;
>> -    AVIOContext *pb = s->pb;
>>      AVCodecParameters *par;
>> -    uint64_t sample_rate;
>> -    int i, aifc = 0;
>> +    int i;
>>
>>      aiff->audio_stream_idx = -1;
>>      for (i = 0; i < s->nb_streams; i++) {
>> @@ -126,6 +124,32 @@ static int aiff_write_header(AVFormatContext *s)
>>      /* First verify if format is ok */
>>      if (!par->codec_tag)
>>          return -1;
>> +
>> +    if (!par->bits_per_coded_sample)
>> +        par->bits_per_coded_sample = av_get_bits_per_sample(par->codec_id);
>> +    if (!par->bits_per_coded_sample) {
>> +        av_log(s, AV_LOG_ERROR, "could not compute bits per sample\n");
>> +        return -1;
>> +    }
>> +    if (!par->block_align)
>> +        par->block_align = (par->bits_per_coded_sample * par->channels) >>
>> 3;
>> +
>> +    avpriv_set_pts_info(s->streams[aiff->audio_stream_idx], 64, 1,
>> +
>> s->streams[aiff->audio_stream_idx]->codecpar->sample_rate);
>> +
>> +    return 0;
>> +}
>> +
>> +static int aiff_write_header(AVFormatContext *s)
>> +{
>> +    AIFFOutputContext *aiff = s->priv_data;
>> +    AVIOContext *pb = s->pb;
>> +    AVCodecParameters *par;
>> +    uint64_t sample_rate;
>> +    int aifc = 0;
>> +
>> +    par = s->streams[aiff->audio_stream_idx]->codecpar;
>> +
>>      if (par->codec_tag != MKTAG('N','O','N','E'))
>>          aifc = 1;
>>
>> @@ -165,15 +189,6 @@ static int aiff_write_header(AVFormatContext *s)
>>      aiff->frames = avio_tell(pb);
>>      avio_wb32(pb, 0);              /* Number of frames */
>>
>> -    if (!par->bits_per_coded_sample)
>> -        par->bits_per_coded_sample = av_get_bits_per_sample(par->codec_id);
>> -    if (!par->bits_per_coded_sample) {
>> -        av_log(s, AV_LOG_ERROR, "could not compute bits per sample\n");
>> -        return -1;
>> -    }
>> -    if (!par->block_align)
>> -        par->block_align = (par->bits_per_coded_sample * par->channels) >>
>> 3;
>> -
>>      avio_wb16(pb, par->bits_per_coded_sample); /* Sample size */
>>
>>      sample_rate = av_double2int(par->sample_rate);
>> @@ -199,9 +214,6 @@ static int aiff_write_header(AVFormatContext *s)
>>      avio_wb32(pb, 0);                    /* Data offset */
>>      avio_wb32(pb, 0);                    /* Block-size (block align) */
>>
>> -    avpriv_set_pts_info(s->streams[aiff->audio_stream_idx], 64, 1,
>> -
>> s->streams[aiff->audio_stream_idx]->codecpar->sample_rate);
>> -
>>      /* Data is starting here */
>>      avio_flush(pb);
>>
>> @@ -327,6 +339,7 @@ AVOutputFormat ff_aiff_muxer = {
>>      .priv_data_size    = sizeof(AIFFOutputContext),
>>      .audio_codec       = AV_CODEC_ID_PCM_S16BE,
>>      .video_codec       = AV_CODEC_ID_PNG,
>> +    .init              = aiff_init,
>>      .write_header      = aiff_write_header,
>>      .write_packet      = aiff_write_packet,
>>      .write_trailer     = aiff_write_trailer,
>> --
>> 2.12.1
>>
>> _______________________________________________
>> ffmpeg-devel mailing list
>> ffmpeg-devel@ffmpeg.org
>> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>>
> 
> Could you explain in detail what this patch does?

This, as well as the previous patch and every other patch that i haven't
yet sent, adds the missing init() function to the muxers so that
initialization is complete without the need to call write_header().
In this specific case, this is achieved by calling
avpriv_set_pts_info(), setting missing AVCodecParameters values and
doing some basic checks in init() instead of in write_header().

With this, calls to avformat_init_output() will return 1 (init complete)
rather than 0 (write_header needed) on most if not all muxers.
The idea is that, eventually, avformat_init_output() will become more
useful and used in ffmpeg.c rather than having it implicitly called from
within avformat_write_header(), to potentially simplify the code in that
file.

Is it useful and will help ffmpeg.c? I don't know, but it's worth a try.
Besides, it's proper to fully initialize the muxer in AVFormat.init()
when possible.

Patch hide | download patch | download mbox

diff --git a/libavformat/aiffenc.c b/libavformat/aiffenc.c
index fcadf149a0..1e0c5b11a0 100644
--- a/libavformat/aiffenc.c
+++ b/libavformat/aiffenc.c
@@ -98,13 +98,11 @@  static void put_meta(AVFormatContext *s, const char *key, uint32_t id)
     }
 }
 
-static int aiff_write_header(AVFormatContext *s)
+static int aiff_init(AVFormatContext *s)
 {
     AIFFOutputContext *aiff = s->priv_data;
-    AVIOContext *pb = s->pb;
     AVCodecParameters *par;
-    uint64_t sample_rate;
-    int i, aifc = 0;
+    int i;
 
     aiff->audio_stream_idx = -1;
     for (i = 0; i < s->nb_streams; i++) {
@@ -126,6 +124,32 @@  static int aiff_write_header(AVFormatContext *s)
     /* First verify if format is ok */
     if (!par->codec_tag)
         return -1;
+
+    if (!par->bits_per_coded_sample)
+        par->bits_per_coded_sample = av_get_bits_per_sample(par->codec_id);
+    if (!par->bits_per_coded_sample) {
+        av_log(s, AV_LOG_ERROR, "could not compute bits per sample\n");
+        return -1;
+    }
+    if (!par->block_align)
+        par->block_align = (par->bits_per_coded_sample * par->channels) >> 3;
+
+    avpriv_set_pts_info(s->streams[aiff->audio_stream_idx], 64, 1,
+                        s->streams[aiff->audio_stream_idx]->codecpar->sample_rate);
+
+    return 0;
+}
+
+static int aiff_write_header(AVFormatContext *s)
+{
+    AIFFOutputContext *aiff = s->priv_data;
+    AVIOContext *pb = s->pb;
+    AVCodecParameters *par;
+    uint64_t sample_rate;
+    int aifc = 0;
+
+    par = s->streams[aiff->audio_stream_idx]->codecpar;
+
     if (par->codec_tag != MKTAG('N','O','N','E'))
         aifc = 1;
 
@@ -165,15 +189,6 @@  static int aiff_write_header(AVFormatContext *s)
     aiff->frames = avio_tell(pb);
     avio_wb32(pb, 0);              /* Number of frames */
 
-    if (!par->bits_per_coded_sample)
-        par->bits_per_coded_sample = av_get_bits_per_sample(par->codec_id);
-    if (!par->bits_per_coded_sample) {
-        av_log(s, AV_LOG_ERROR, "could not compute bits per sample\n");
-        return -1;
-    }
-    if (!par->block_align)
-        par->block_align = (par->bits_per_coded_sample * par->channels) >> 3;
-
     avio_wb16(pb, par->bits_per_coded_sample); /* Sample size */
 
     sample_rate = av_double2int(par->sample_rate);
@@ -199,9 +214,6 @@  static int aiff_write_header(AVFormatContext *s)
     avio_wb32(pb, 0);                    /* Data offset */
     avio_wb32(pb, 0);                    /* Block-size (block align) */
 
-    avpriv_set_pts_info(s->streams[aiff->audio_stream_idx], 64, 1,
-                        s->streams[aiff->audio_stream_idx]->codecpar->sample_rate);
-
     /* Data is starting here */
     avio_flush(pb);
 
@@ -327,6 +339,7 @@  AVOutputFormat ff_aiff_muxer = {
     .priv_data_size    = sizeof(AIFFOutputContext),
     .audio_codec       = AV_CODEC_ID_PCM_S16BE,
     .video_codec       = AV_CODEC_ID_PNG,
+    .init              = aiff_init,
     .write_header      = aiff_write_header,
     .write_packet      = aiff_write_packet,
     .write_trailer     = aiff_write_trailer,