[FFmpeg-devel] [PATCH] New API usage example (it converts, encodes, muxes a raw audio file and shows how to use a custom callback for muxing, with an allocated I/O context)

2019-04-18 Thread Paolo Prete
I think this example can be useful for showing all the above tasks in an 
ordered,
easy and strictly sequential way, with a kind of input close to the user's 
needings.

Signed-off-by: Paolo Prete 
---
 configure   |   2 +
 doc/examples/Makefile   |  47 ++--
 doc/examples/Makefile.example   |   1 +
 doc/examples/convert_encode_mux_audio.c | 349 
 4 files changed, 376 insertions(+), 23 deletions(-)
 create mode 100644 doc/examples/convert_encode_mux_audio.c

diff --git a/configure b/configure
index e10e2c2c46..1ae62ebdd5 100755
--- a/configure
+++ b/configure
@@ -1653,6 +1653,7 @@ COMPONENT_LIST="
 EXAMPLE_LIST="
 avio_dir_cmd_example
 avio_reading_example
+convert_encode_mux_audio_example
 decode_audio_example
 decode_video_example
 demuxing_decoding_example
@@ -3539,6 +3540,7 @@ yadif_cuda_filter_deps="ffnvcodec cuda_nvcc"
 # examples
 avio_dir_cmd_deps="avformat avutil"
 avio_reading_deps="avformat avcodec avutil"
+convert_encode_mux_audio_example_deps="avformat avcodec swresample"
 decode_audio_example_deps="avcodec avutil"
 decode_video_example_deps="avcodec avutil"
 demuxing_decoding_example_deps="avcodec avformat avutil"
diff --git a/doc/examples/Makefile b/doc/examples/Makefile
index 2935424e54..7b7855fa27 100644
--- a/doc/examples/Makefile
+++ b/doc/examples/Makefile
@@ -1,26 +1,27 @@
-EXAMPLES-$(CONFIG_AVIO_DIR_CMD_EXAMPLE)  += avio_dir_cmd
-EXAMPLES-$(CONFIG_AVIO_READING_EXAMPLE)  += avio_reading
-EXAMPLES-$(CONFIG_DECODE_AUDIO_EXAMPLE)  += decode_audio
-EXAMPLES-$(CONFIG_DECODE_VIDEO_EXAMPLE)  += decode_video
-EXAMPLES-$(CONFIG_DEMUXING_DECODING_EXAMPLE) += demuxing_decoding
-EXAMPLES-$(CONFIG_ENCODE_AUDIO_EXAMPLE)  += encode_audio
-EXAMPLES-$(CONFIG_ENCODE_VIDEO_EXAMPLE)  += encode_video
-EXAMPLES-$(CONFIG_EXTRACT_MVS_EXAMPLE)   += extract_mvs
-EXAMPLES-$(CONFIG_FILTER_AUDIO_EXAMPLE)  += filter_audio
-EXAMPLES-$(CONFIG_FILTERING_AUDIO_EXAMPLE)   += filtering_audio
-EXAMPLES-$(CONFIG_FILTERING_VIDEO_EXAMPLE)   += filtering_video
-EXAMPLES-$(CONFIG_HTTP_MULTICLIENT_EXAMPLE)  += http_multiclient
-EXAMPLES-$(CONFIG_HW_DECODE_EXAMPLE) += hw_decode
-EXAMPLES-$(CONFIG_METADATA_EXAMPLE)  += metadata
-EXAMPLES-$(CONFIG_MUXING_EXAMPLE)+= muxing
-EXAMPLES-$(CONFIG_QSVDEC_EXAMPLE)+= qsvdec
-EXAMPLES-$(CONFIG_REMUXING_EXAMPLE)  += remuxing
-EXAMPLES-$(CONFIG_RESAMPLING_AUDIO_EXAMPLE)  += resampling_audio
-EXAMPLES-$(CONFIG_SCALING_VIDEO_EXAMPLE) += scaling_video
-EXAMPLES-$(CONFIG_TRANSCODE_AAC_EXAMPLE) += transcode_aac
-EXAMPLES-$(CONFIG_TRANSCODING_EXAMPLE)   += transcoding
-EXAMPLES-$(CONFIG_VAAPI_ENCODE_EXAMPLE)  += vaapi_encode
-EXAMPLES-$(CONFIG_VAAPI_TRANSCODE_EXAMPLE)   += vaapi_transcode
+EXAMPLES-$(CONFIG_AVIO_DIR_CMD_EXAMPLE) += avio_dir_cmd
+EXAMPLES-$(CONFIG_AVIO_READING_EXAMPLE) += avio_reading
+EXAMPLES-$(CONFIG_CONVERT_ENCODE_MUX_AUDIO_EXAMPLE) += convert_encode_mux_audio
+EXAMPLES-$(CONFIG_DECODE_AUDIO_EXAMPLE) += decode_audio
+EXAMPLES-$(CONFIG_DECODE_VIDEO_EXAMPLE) += decode_video
+EXAMPLES-$(CONFIG_DEMUXING_DECODING_EXAMPLE)+= demuxing_decoding
+EXAMPLES-$(CONFIG_ENCODE_AUDIO_EXAMPLE) += encode_audio
+EXAMPLES-$(CONFIG_ENCODE_VIDEO_EXAMPLE) += encode_video
+EXAMPLES-$(CONFIG_EXTRACT_MVS_EXAMPLE)  += extract_mvs
+EXAMPLES-$(CONFIG_FILTER_AUDIO_EXAMPLE) += filter_audio
+EXAMPLES-$(CONFIG_FILTERING_AUDIO_EXAMPLE)  += filtering_audio
+EXAMPLES-$(CONFIG_FILTERING_VIDEO_EXAMPLE)  += filtering_video
+EXAMPLES-$(CONFIG_HTTP_MULTICLIENT_EXAMPLE) += http_multiclient
+EXAMPLES-$(CONFIG_HW_DECODE_EXAMPLE)+= hw_decode
+EXAMPLES-$(CONFIG_METADATA_EXAMPLE) += metadata
+EXAMPLES-$(CONFIG_MUXING_EXAMPLE)   += muxing
+EXAMPLES-$(CONFIG_QSVDEC_EXAMPLE)   += qsvdec
+EXAMPLES-$(CONFIG_REMUXING_EXAMPLE) += remuxing
+EXAMPLES-$(CONFIG_RESAMPLING_AUDIO_EXAMPLE) += resampling_audio
+EXAMPLES-$(CONFIG_SCALING_VIDEO_EXAMPLE)+= scaling_video
+EXAMPLES-$(CONFIG_TRANSCODE_AAC_EXAMPLE)+= transcode_aac
+EXAMPLES-$(CONFIG_TRANSCODING_EXAMPLE)  += transcoding
+EXAMPLES-$(CONFIG_VAAPI_ENCODE_EXAMPLE) += vaapi_encode
+EXAMPLES-$(CONFIG_VAAPI_TRANSCODE_EXAMPLE)  += vaapi_transcode
 
 EXAMPLES   := $(EXAMPLES-yes:%=doc/examples/%$(PROGSSUF)$(EXESUF))
 EXAMPLES_G := $(EXAMPLES-yes:%=doc/examples/%$(PROGSSUF)_g$(EXESUF))
diff --git a/doc/examples/Makefile.example b/doc/examples/Makefile.example
index 6428154c51..04e5c902a8 100644
--- a/doc/examples/Makefile.example
+++ b/doc/examples/Makefile.example
@@ -15,6 +15,7 @@ EXAMPLES=   avio_dir_cmd   

Re: [FFmpeg-devel] [Libav-user] New libav API usage axamples

2017-03-27 Thread Paolo Prete
Il Lunedì 27 Marzo 2017 10:05, Carl Eugen Hoyos  ha scritto:


 

 2017-03-27 9:11 GMT+02:00 Gabor Alsecz :

> Thanks for the code snippet you have pasted here. Many of us
> struggling here because lack of samples even based on the latest API.
> I just can confirm to the Libav team we really would need new API
> examples and please try to figure out the way how Paolo can share
> his snippets commonly.

(Speaking for FFmpeg, not any forks)
If the snippets provide advantages over the code in doc/examples,
please send your patch (against current FFmpeg git head) made
with git format-patch to the FFmpeg development mailing list.
This is also where the feedback comes from.

Carl Eugen
___
Libav-user mailing list
libav-u...@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/libav-user





Hello,
The snippet I posted could provide these advantages:
1) it can easily be adapted to any audio input source (i.e: a live source)
2) it is short and written in a strict procedural way, without using any 
function which splits the code with the result of forcing the reader/user to 
jump from a line to another one in order to understand in details what's 
happening.
3) all the tasks are separated and all of them are exposed to the user without 
using functions which hide internal tasks/containers; i.e: muxed data is stored 
in memory and exposed through a callback function. Therefore, the user can pick 
specific portions of the code (input raw frame, resampled frame, encoded packet 
and muxed data) and adapt them to his needings.
4) it can be easily adapted to other audio codecs: I used the aac one, in the 
example, because it requires a container (adts), then it improves the basic 
knowledge of the API; but the user can adapt the snippet to mp2 codec, for 
example, by simply removing the container part, and he can directly write to 
file the encoded packets.
5) The cleanup stuff is divided into steps.

This message is cross-posted to the ffmpeg-devel mailing list and includes the 
previous snippet in form of patches in git format-patch (Makefile and snippet 
files). If it will be accepted, I can provide the next example, which covers 
h264 encoding, muxing and streaming.



   From 9e5f3d83bf42b987386a0566a8b4554315e336e8 Mon Sep 17 00:00:00 2001
From: Paolo Prete 
Date: Mon, 27 Mar 2017 23:09:07 +0200
Subject: [PATCH] Makefile changed in order to include a new API usage example
 (encode_raw_audio_file_to_aac.c)

---
 doc/examples/Makefile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/doc/examples/Makefile b/doc/examples/Makefile
index af38159..f316bfb 100644
--- a/doc/examples/Makefile
+++ b/doc/examples/Makefile
@@ -15,6 +15,7 @@ EXAMPLES=   avio_dir_cmd   \
 avio_reading   \
 decoding_encoding  \
 demuxing_decoding  \
+		encode_raw_audio_file_to_aac   \
 extract_mvs\
 filtering_video\
 filtering_audio\
-- 
2.9.3

From 3d7afbccf35186890b5b8151342cb17dfc9d38e4 Mon Sep 17 00:00:00 2001
From: Paolo Prete 
Date: Mon, 27 Mar 2017 23:07:12 +0200
Subject: [PATCH] new API usage example

---
 doc/examples/encode_raw_audio_file_to_aac.c | 326 
 1 file changed, 326 insertions(+)
 create mode 100644 doc/examples/encode_raw_audio_file_to_aac.c

diff --git a/doc/examples/encode_raw_audio_file_to_aac.c b/doc/examples/encode_raw_audio_file_to_aac.c
new file mode 100644
index 000..045df33
--- /dev/null
+++ b/doc/examples/encode_raw_audio_file_to_aac.c
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2017 Paolo Prete (p4olo_pr...@yahoo.it)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/**
+ * @file
+ * API example for adts-aac encoding raw audio files. 
+ * T

[FFmpeg-devel] [PATCH] new API usage example (adts-aac encoding from raw audio file)

2017-03-28 Thread Paolo Prete
---
 doc/examples/Makefile   |   1 +
 doc/examples/encode_raw_audio_file_to_aac.c | 275 
 2 files changed, 276 insertions(+)
 create mode 100644 doc/examples/encode_raw_audio_file_to_aac.c

diff --git a/doc/examples/Makefile b/doc/examples/Makefile
index af38159..81181c7 100644
--- a/doc/examples/Makefile
+++ b/doc/examples/Makefile
@@ -15,6 +15,7 @@ EXAMPLES=   avio_dir_cmd   \
 avio_reading   \
 decoding_encoding  \
 demuxing_decoding  \
+encode_raw_audio_file_to_aac   \
 extract_mvs\
 filtering_video\
 filtering_audio\
diff --git a/doc/examples/encode_raw_audio_file_to_aac.c 
b/doc/examples/encode_raw_audio_file_to_aac.c
new file mode 100644
index 000..19114e8
--- /dev/null
+++ b/doc/examples/encode_raw_audio_file_to_aac.c
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2017 Paolo Prete (p4olo_pr...@yahoo.it)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/**
+ * @file
+ * API example for adts-aac encoding raw audio files. 
+ * This example reads a raw audio input file, converts it to float-planar 
format, performs aac encoding and puts the encoded frames into an ADTS 
container. The encoded stream is written to 
+ * a file named "out.aac"
+ * The raw input audio file can be created with: ffmpeg -i some_audio_file -f 
f32le -acodec pcm_f32le -ac 2 -ar 16000 raw_audio_file.raw
+ * 
+ * @example encode_raw_audio_file_to_aac.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#define ENCODER_BITRATE 64000
+#define SAMPLE_RATE 16000
+#define INPUT_SAMPLE_FMT AV_SAMPLE_FMT_FLT
+#define CHANNELS 2
+
+static int write_adts_muxed_data (void *opaque, uint8_t *adts_data, int size)
+{
+FILE *encoded_audio_file = (FILE *)opaque;
+fwrite(adts_data, 1, size, encoded_audio_file); //(f)
+return size;
+}
+
+int main(int argc, char **argv)
+{
+FILE *input_audio_file = NULL, *encoded_audio_file = NULL;
+AVCodec *audio_codec = NULL;
+AVCodecContext *audio_encoder_ctx = NULL;
+AVFrame *input_audio_frame = NULL, *converted_audio_frame = NULL;
+SwrContext *audio_convert_context = NULL;
+AVOutputFormat *adts_container = NULL;
+AVFormatContext *adts_container_ctx = NULL;
+uint8_t *adts_container_buffer = NULL;
+size_t adts_container_buffer_size = 4096;
+AVIOContext *adts_avio_ctx = NULL;
+AVStream *adts_stream = NULL;  
+AVPacket encoded_audio_packet;
+int encoded_pkt_counter = 1;
+int still_pkts_to_flush = 1;
+int delayed_pkt_counter = 1;
+int ret_val = 0;
+int audio_bytes_to_encode;
+int64_t curr_pts;
+
+if (argc != 2) {
+printf("Usage: %s \n", argv[0]);
+return 1;
+}
+
+input_audio_file = fopen(argv[1], "rb");
+if (!input_audio_file) {
+av_log(NULL, AV_LOG_ERROR, "Could not open input audio file\n");
+return AVERROR_EXIT;
+}
+
+encoded_audio_file = fopen("out.aac", "wb");  
+if (!encoded_audio_file) {
+av_log(NULL, AV_LOG_ERROR, "Could not open output audio file\n");
+fclose(input_audio_file);
+return AVERROR_EXIT;
+}
+
+av_register_all();
+
+/**
+* Allocate the encoder's context and open the encoder
+*/
+audio_codec = avcodec_find_encoder(AV_CODEC_ID_AAC);
+if (!audio_codec) {
+av_log(NULL, AV_LOG_ERROR, "Could not find aac codec\n");
+ret_val = AVERROR_EXIT;
+goto end;
+}
+audio_encoder_ctx = avcodec_alloc_context3(audio_codec);
+if (!audio_codec) {
+av_log(NULL, AV_LOG_ERROR, "Could not allocate the encodi

Re: [FFmpeg-devel] [PATCH] new API usage example (adts-aac encoding from raw audio file)

2017-03-29 Thread Paolo Prete
 

Il Mercoledì 29 Marzo 2017 11:58, wm4  ha scritto:
 
> There are vague plans of disallowing stack allocation of AVPackets by> 
> removing sizeof(AVPacket) from the ABI (like AVFrame etc.), so it might> be 
> better to allocate the packet with the appropriate functions.
Done. (see next patch)


> This function is obviously getting a bit too long. Why not split it> into 
> multiple functions?
Because without functions, the sequence of operations is more clear and easier 
to read and modify, IMHO, and the user doesn't have to jump from a line to 
another one in order to understand the code (which is short) in details. The 
same functions would be called once, and I don't think this is good. Consider 
that this is an API USAGE example, not a real application.Anyway, this is a 
personal opinion, and if you (and ffmpeg team) think it's better to use these 
functions, I'll add them to the code.


> Some encoders (probably not all) signal what rates and formats they> support 
> in the AVCodec struct.
Done for the samplerates (see next patch). About the formats, I left a fixed 
AV_SAMPLE_FMT_FLTP, given that I see that the aac codec only accepts this 
format.


> The code would be much easier if not using custom I/O...
The choice of custom I/O is strongly intentional given that it provides access 
to muxed packets written in memory, and this can be useful for user if they 
decide to manage these packets. I don't think that's much harder: it consists 
only of a simple buffer and a 3-lines callback function. Anyway, I added 
comment that a custom I/O is intentionally used for the reason I just explained 
(see next patch)


> Like I said somewhere else, it _might_ be better to wait with that until the 
> first packet has been encoded (maybe not with the AAC encoder, but some 
> others potentially). I'll leave this to > others to judge though.
Waiting for other feedbacks, then...


> What's with the const cast?
I casted the input frame according to the function declaration and according to 
what other examples do with a similar function (see swr_convert() call in 
resampling_audio.c)


> You need av_frame_make_writeable() on the output frame.
Done (see next patch)


> Also doesn't check for errors.
Done (see next patch)


> Errors in ret_val are discarded?
Corrected in this way (see next patch): I discarded only the EAGAIN return val. 
Should be ok but I need a feedback. Not sure if it must be added for the cached 
pkts too.


> Also, if you put the receive call in a loop, it'd actually follow the proper 
> send/receive data flow.
What do you mean exactly? The receive call is already in a loop (while (1))


> This call ( avcodec_send_frame() ) is needed only once.
Done (see next patch)


> Not sure why this logging is done - just seems to inflate the code.
Removed (see next patch)


> I don't remember how the swr_convert_frame API works, but you might have to 
> flush out the resampler too.
This is needed (as the API doc says) when converting sample rate, which doesn't 
happen in this example


   
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] new API usage example (adts-aac encoding from raw audio file)

2017-03-29 Thread Paolo Prete
---
 doc/examples/Makefile   |   1 +
 doc/examples/encode_raw_audio_file_to_aac.c | 300 
 2 files changed, 301 insertions(+)
 create mode 100644 doc/examples/encode_raw_audio_file_to_aac.c

diff --git a/doc/examples/Makefile b/doc/examples/Makefile
index af38159..81181c7 100644
--- a/doc/examples/Makefile
+++ b/doc/examples/Makefile
@@ -15,6 +15,7 @@ EXAMPLES=   avio_dir_cmd   \
 avio_reading   \
 decoding_encoding  \
 demuxing_decoding  \
+encode_raw_audio_file_to_aac   \
 extract_mvs\
 filtering_video\
 filtering_audio\
diff --git a/doc/examples/encode_raw_audio_file_to_aac.c 
b/doc/examples/encode_raw_audio_file_to_aac.c
new file mode 100644
index 000..546e713
--- /dev/null
+++ b/doc/examples/encode_raw_audio_file_to_aac.c
@@ -0,0 +1,300 @@
+/*
+ * Copyright (c) 2017 Paolo Prete (p4olo_pr...@yahoo.it)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/**
+ * @file
+ * API example for adts-aac encoding raw audio files. 
+ * This example reads a raw audio input file, converts it to float-planar 
format, performs aac encoding and puts the encoded frames into an ADTS 
container. The encoded stream is written to 
+ * a file named "out.aac"
+ * The raw input audio file can be created with: ffmpeg -i some_audio_file -f 
f32le -acodec pcm_f32le -ac 2 -ar 16000 raw_audio_file.raw
+ * 
+ * @example encode_raw_audio_file_to_aac.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#define ENCODER_BITRATE 64000
+#define SAMPLE_RATE 16000
+#define INPUT_SAMPLE_FMT AV_SAMPLE_FMT_FLT
+#define CHANNELS 2
+
+static int encoded_pkt_counter = 1;
+
+static int write_adts_muxed_data(void *opaque, uint8_t *adts_data, int size)
+{
+FILE *encoded_audio_file = (FILE *)opaque;
+fwrite(adts_data, 1, size, encoded_audio_file); //(f)
+return size;
+}
+
+static int mux_aac_packet_to_adts (AVPacket *encoded_audio_packet, 
AVFormatContext *adts_container_ctx)
+{
+int ret_val;
+if ((ret_val == av_write_frame(adts_container_ctx, encoded_audio_packet)) 
< 0) {
+av_log(NULL, AV_LOG_ERROR, "Error calling av_write_frame() (error 
'%s')\n", av_err2str(ret_val));
+}
+else {
+av_log(NULL, AV_LOG_INFO, "Encoded AAC packet %d, size=%d, 
pts_time=%s\n", encoded_pkt_counter, encoded_audio_packet->size, 
av_ts2timestr(encoded_audio_packet->pts, 
&adts_container_ctx->streams[0]->time_base));
+}
+return ret_val;
+}
+
+static int check_if_samplerate_is_supported(AVCodec *audio_codec, int 
samplerate)
+{
+const int *samplerates_list = audio_codec->supported_samplerates;
+while (*samplerates_list) {
+if (*samplerates_list == samplerate)
+return 0;
+++samplerates_list;  
+}
+return 1;
+}
+
+int main(int argc, char **argv)
+{
+FILE *input_audio_file = NULL, *encoded_audio_file = NULL;
+AVCodec *audio_codec = NULL;
+AVCodecContext *audio_encoder_ctx = NULL;
+AVFrame *input_audio_frame = NULL, *converted_audio_frame = NULL;
+SwrContext *audio_convert_context = NULL;
+AVOutputFormat *adts_container = NULL;
+AVFormatContext *adts_container_ctx = NULL;
+uint8_t *adts_container_buffer = NULL;
+size_t adts_container_buffer_size = 4096;
+AVIOContext *adts_avio_ctx = NULL;
+AVStream *adts_stream = NULL;  
+AVPacket *encoded_audio_packet = NULL;
+int ret_val = 0;
+int audio_bytes_to_encode;
+int64_t curr_pts;
+
+if (argc != 2) {
+printf("Usage: %s \n", argv[0]);
+return 1;
+}
+
+input_audio_file = fopen(argv[1], "rb")

Re: [FFmpeg-devel] [PATCH] new API usage example (adts-aac encoding from raw audio file)

2017-03-29 Thread Paolo Prete
Sorry, the previous patch contains few typo errors. See the next one. 

Il Giovedì 30 Marzo 2017 1:00, Paolo Prete 
 ha scritto:
 

 ---
 doc/examples/Makefile                      |  1 +
 doc/examples/encode_raw_audio_file_to_aac.c | 300 
 2 files changed, 301 insertions(+)
 create mode 100644 doc/examples/encode_raw_audio_file_to_aac.c

diff --git a/doc/examples/Makefile b/doc/examples/Makefile
index af38159..81181c7 100644
--- a/doc/examples/Makefile
+++ b/doc/examples/Makefile
@@ -15,6 +15,7 @@ EXAMPLES=      avio_dir_cmd                      \
                avio_reading                      \
                decoding_encoding                  \
                demuxing_decoding                  \
+                encode_raw_audio_file_to_aac      \
                extract_mvs                        \
                filtering_video                    \
                filtering_audio                    \
diff --git a/doc/examples/encode_raw_audio_file_to_aac.c 
b/doc/examples/encode_raw_audio_file_to_aac.c
new file mode 100644
index 000..546e713
--- /dev/null
+++ b/doc/examples/encode_raw_audio_file_to_aac.c
@@ -0,0 +1,300 @@
+/*
+ * Copyright (c) 2017 Paolo Prete (p4olo_pr...@yahoo.it)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/**
+ * @file
+ * API example for adts-aac encoding raw audio files. 
+ * This example reads a raw audio input file, converts it to float-planar 
format, performs aac encoding and puts the encoded frames into an ADTS 
container. The encoded stream is written to 
+ * a file named "out.aac"
+ * The raw input audio file can be created with: ffmpeg -i some_audio_file -f 
f32le -acodec pcm_f32le -ac 2 -ar 16000 raw_audio_file.raw
+ * 
+ * @example encode_raw_audio_file_to_aac.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#define ENCODER_BITRATE 64000
+#define SAMPLE_RATE 16000
+#define INPUT_SAMPLE_FMT AV_SAMPLE_FMT_FLT
+#define CHANNELS 2
+
+static int encoded_pkt_counter = 1;
+
+static int write_adts_muxed_data(void *opaque, uint8_t *adts_data, int size)
+{
+    FILE *encoded_audio_file = (FILE *)opaque;
+    fwrite(adts_data, 1, size, encoded_audio_file); //(f)
+    return size;
+}
+
+static int mux_aac_packet_to_adts (AVPacket *encoded_audio_packet, 
AVFormatContext *adts_container_ctx)
+{
+    int ret_val;
+    if ((ret_val == av_write_frame(adts_container_ctx, encoded_audio_packet)) 
< 0) {
+        av_log(NULL, AV_LOG_ERROR, "Error calling av_write_frame() (error 
'%s')\n", av_err2str(ret_val));
+    }
+    else {
+        av_log(NULL, AV_LOG_INFO, "Encoded AAC packet %d, size=%d, 
pts_time=%s\n", encoded_pkt_counter, encoded_audio_packet->size, 
av_ts2timestr(encoded_audio_packet->pts, 
&adts_container_ctx->streams[0]->time_base));
+    }
+    return ret_val;
+}
+
+static int check_if_samplerate_is_supported(AVCodec *audio_codec, int 
samplerate)
+{
+    const int *samplerates_list = audio_codec->supported_samplerates;
+    while (*samplerates_list) {
+        if (*samplerates_list == samplerate)
+            return 0;
+        ++samplerates_list;      
+    }
+    return 1;
+}
+
+int main(int argc, char **argv)
+{
+    FILE *input_audio_file = NULL, *encoded_audio_file = NULL;
+    AVCodec *audio_codec = NULL;
+    AVCodecContext *audio_encoder_ctx = NULL;
+    AVFrame *input_audio_frame = NULL, *converted_audio_frame = NULL;
+    SwrContext *audio_convert_context = NULL;
+    AVOutputFormat *adts_container = NULL;
+    AVFormatContext *adts_container_ctx = NULL;
+    uint8_t *adts_container_buffer = NULL;
+    size_t adts_container_buffer_size = 4096;
+    AVIOContext *adts_avio_ctx = NULL;
+    AVStream *adts_stream = NULL;  
+    AVPacket *encoded_audio_packet = NULL;
+    int ret_val = 0;
+    int audio_bytes_to_encode;
+    int64_t curr_pts;
+    
+    if (argc != 2) {
+        printf("Usage: %

[FFmpeg-devel] [PATCH] new API usage example (adts-aac encoding from raw audio file)

2017-03-29 Thread Paolo Prete
---
 doc/examples/Makefile   |   1 +
 doc/examples/encode_raw_audio_file_to_aac.c | 300 
 2 files changed, 301 insertions(+)
 create mode 100644 doc/examples/encode_raw_audio_file_to_aac.c

diff --git a/doc/examples/Makefile b/doc/examples/Makefile
index af38159..81181c7 100644
--- a/doc/examples/Makefile
+++ b/doc/examples/Makefile
@@ -15,6 +15,7 @@ EXAMPLES=   avio_dir_cmd   \
 avio_reading   \
 decoding_encoding  \
 demuxing_decoding  \
+encode_raw_audio_file_to_aac   \
 extract_mvs\
 filtering_video\
 filtering_audio\
diff --git a/doc/examples/encode_raw_audio_file_to_aac.c 
b/doc/examples/encode_raw_audio_file_to_aac.c
new file mode 100644
index 000..269522e
--- /dev/null
+++ b/doc/examples/encode_raw_audio_file_to_aac.c
@@ -0,0 +1,300 @@
+/*
+ * Copyright (c) 2017 Paolo Prete (p4olo_pr...@yahoo.it)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/**
+ * @file
+ * API example for adts-aac encoding raw audio files. 
+ * This example reads a raw audio input file, converts it to float-planar 
format, performs aac encoding and puts the encoded frames into an ADTS 
container. The encoded stream is written to 
+ * a file named "out.aac"
+ * The raw input audio file can be created with: ffmpeg -i some_audio_file -f 
f32le -acodec pcm_f32le -ac 2 -ar 16000 raw_audio_file.raw
+ * 
+ * @example encode_raw_audio_file_to_aac.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#define ENCODER_BITRATE 64000
+#define SAMPLE_RATE 16000
+#define INPUT_SAMPLE_FMT AV_SAMPLE_FMT_FLT
+#define CHANNELS 2
+
+static int encoded_pkt_counter = 1;
+
+static int write_adts_muxed_data(void *opaque, uint8_t *adts_data, int size)
+{
+FILE *encoded_audio_file = (FILE *)opaque;
+fwrite(adts_data, 1, size, encoded_audio_file); //(f)
+return size;
+}
+
+static int mux_aac_packet_to_adts (AVPacket *encoded_audio_packet, 
AVFormatContext *adts_container_ctx)
+{
+int ret_val;
+if ((ret_val = av_write_frame(adts_container_ctx, encoded_audio_packet)) < 
0) {
+av_log(NULL, AV_LOG_ERROR, "Error calling av_write_frame() (error 
'%s')\n", av_err2str(ret_val));
+}
+else {
+av_log(NULL, AV_LOG_INFO, "Encoded AAC packet %d, size=%d, 
pts_time=%s\n", encoded_pkt_counter, encoded_audio_packet->size, 
av_ts2timestr(encoded_audio_packet->pts, 
&adts_container_ctx->streams[0]->time_base));
+}
+return ret_val;
+}
+
+static int check_if_samplerate_is_supported(AVCodec *audio_codec, int 
samplerate)
+{
+const int *samplerates_list = audio_codec->supported_samplerates;
+while (*samplerates_list) {
+if (*samplerates_list == samplerate)
+return 0;
+++samplerates_list;  
+}
+return 1;
+}
+
+int main(int argc, char **argv)
+{
+FILE *input_audio_file = NULL, *encoded_audio_file = NULL;
+AVCodec *audio_codec = NULL;
+AVCodecContext *audio_encoder_ctx = NULL;
+AVFrame *input_audio_frame = NULL, *converted_audio_frame = NULL;
+SwrContext *audio_convert_context = NULL;
+AVOutputFormat *adts_container = NULL;
+AVFormatContext *adts_container_ctx = NULL;
+uint8_t *adts_container_buffer = NULL;
+size_t adts_container_buffer_size = 4096;
+AVIOContext *adts_avio_ctx = NULL;
+AVStream *adts_stream = NULL;  
+AVPacket *encoded_audio_packet = NULL;
+int ret_val = 0;
+int audio_bytes_to_encode;
+int64_t curr_pts;
+
+if (argc != 2) {
+printf("Usage: %s \n", argv[0]);
+return 1;
+}
+
+input_audio_file = fopen(argv[1], "rb")

Re: [FFmpeg-devel] [PATCH] new API usage example (adts-aac encoding from raw audio file)

2017-03-29 Thread Paolo Prete
Il Giovedì 30 Marzo 2017 1:43, Paolo Prete  
ha scritto:


 
The next patch I'm going to post adds a check with av_frame_make_writable(), as 
suggested by wm4. However, I see that the same function is used only by 
muxing.c in the examples folder, and it's not clear which kind of error could 
it raise.
   
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] new API usage example (adts-aac encoding from raw audio file, added av_frame_make_writable() check)

2017-03-29 Thread Paolo Prete
---
 doc/examples/Makefile   |   1 +
 doc/examples/encode_raw_audio_file_to_aac.c | 307 
 2 files changed, 308 insertions(+)
 create mode 100644 doc/examples/encode_raw_audio_file_to_aac.c

diff --git a/doc/examples/Makefile b/doc/examples/Makefile
index af38159..81181c7 100644
--- a/doc/examples/Makefile
+++ b/doc/examples/Makefile
@@ -15,6 +15,7 @@ EXAMPLES=   avio_dir_cmd   \
 avio_reading   \
 decoding_encoding  \
 demuxing_decoding  \
+encode_raw_audio_file_to_aac   \
 extract_mvs\
 filtering_video\
 filtering_audio\
diff --git a/doc/examples/encode_raw_audio_file_to_aac.c 
b/doc/examples/encode_raw_audio_file_to_aac.c
new file mode 100644
index 000..140aff6
--- /dev/null
+++ b/doc/examples/encode_raw_audio_file_to_aac.c
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 2017 Paolo Prete (p4olo_pr...@yahoo.it)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/**
+ * @file
+ * API example for adts-aac encoding raw audio files. 
+ * This example reads a raw audio input file, converts it to float-planar 
format, performs aac encoding and puts the encoded frames into an ADTS 
container. The encoded stream is written to 
+ * a file named "out.aac"
+ * The raw input audio file can be created with: ffmpeg -i some_audio_file -f 
f32le -acodec pcm_f32le -ac 2 -ar 16000 raw_audio_file.raw
+ * 
+ * @example encode_raw_audio_file_to_aac.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#define ENCODER_BITRATE 64000
+#define SAMPLE_RATE 16000
+#define INPUT_SAMPLE_FMT AV_SAMPLE_FMT_FLT
+#define CHANNELS 2
+
+static int encoded_pkt_counter = 1;
+
+static int write_adts_muxed_data(void *opaque, uint8_t *adts_data, int size)
+{
+FILE *encoded_audio_file = (FILE *)opaque;
+fwrite(adts_data, 1, size, encoded_audio_file); //(f)
+return size;
+}
+
+static int mux_aac_packet_to_adts (AVPacket *encoded_audio_packet, 
AVFormatContext *adts_container_ctx)
+{
+int ret_val;
+if ((ret_val = av_write_frame(adts_container_ctx, encoded_audio_packet)) < 
0) {
+av_log(NULL, AV_LOG_ERROR, "Error calling av_write_frame() (error 
'%s')\n", av_err2str(ret_val));
+}
+else {
+av_log(NULL, AV_LOG_INFO, "Encoded AAC packet %d, size=%d, 
pts_time=%s\n", encoded_pkt_counter, encoded_audio_packet->size, 
av_ts2timestr(encoded_audio_packet->pts, 
&adts_container_ctx->streams[0]->time_base));
+}
+return ret_val;
+}
+
+static int check_if_samplerate_is_supported(AVCodec *audio_codec, int 
samplerate)
+{
+const int *samplerates_list = audio_codec->supported_samplerates;
+while (*samplerates_list) {
+if (*samplerates_list == samplerate)
+return 0;
+++samplerates_list;  
+}
+return 1;
+}
+
+int main(int argc, char **argv)
+{
+FILE *input_audio_file = NULL, *encoded_audio_file = NULL;
+AVCodec *audio_codec = NULL;
+AVCodecContext *audio_encoder_ctx = NULL;
+AVFrame *input_audio_frame = NULL, *converted_audio_frame = NULL;
+SwrContext *audio_convert_context = NULL;
+AVOutputFormat *adts_container = NULL;
+AVFormatContext *adts_container_ctx = NULL;
+uint8_t *adts_container_buffer = NULL;
+size_t adts_container_buffer_size = 4096;
+AVIOContext *adts_avio_ctx = NULL;
+AVStream *adts_stream = NULL;  
+AVPacket *encoded_audio_packet = NULL;
+int ret_val = 0;
+int audio_bytes_to_encode;
+int64_t curr_pts;
+
+if (argc != 2) {
+printf("Usage: %s \n", argv[0]);
+return 1;
+}
+
+input_audio_file = fopen(argv[1], "rb")

[FFmpeg-devel] [PATCH] New API usage example (encode_raw_audio_file_to_aac)

2017-03-30 Thread Paolo Prete
doc/examples/Makefile
index 2d0a306..24929e3 100644
--- a/doc/examples/Makefile
+++ b/doc/examples/Makefile
@@ -17,6 +17,7 @@ EXAMPLES=   avio_dir_cmd   \
 decode_video   \
 demuxing_decoding  \
 encode_audio   \
+encode_raw_audio_file_to_aac   \
 encode_video   \
 extract_mvs\
 filtering_video\
diff --git a/doc/examples/encode_raw_audio_file_to_aac.c 
b/doc/examples/encode_raw_audio_file_to_aac.c
new file mode 100644
index 000..5e6df5c
--- /dev/null
+++ b/doc/examples/encode_raw_audio_file_to_aac.c
@@ -0,0 +1,338 @@
+/*
+ * Copyright (c) 2017 Paolo Prete (p4olo_pr...@yahoo.it)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/**
+ * @file
+ * API example for adts-aac encoding raw audio files. 
+ * This example reads a raw audio input file, converts it to float-planar 
format, performs 
+ * aac encoding and puts the encoded frames into an ADTS container. 
+ * The encoded stream is written to a file named "out.aac"
+ * It can be adapted, with few changes, to a custom raw audio source (i.e: a 
live one). 
+ * It uses a custom I/O write callback (write_adts_muxed_data()) in order to 
show to the user 
+ * how to access muxed packets written in memory, before they are written to 
the output file.
+ * The raw input audio file can be created with: 
+ * 
+ * ffmpeg -i some_audio_file -f f32le -acodec pcm_f32le -ac 2 -ar 16000 
raw_audio_file.raw
+ * 
+ * @example encode_raw_audio_file_to_aac.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#define ENCODER_BITRATE 64000
+#define SAMPLE_RATE 16000
+#define INPUT_SAMPLE_FMT AV_SAMPLE_FMT_FLT
+#define CHANNELS 2
+
+static int encoded_pkt_counter = 1;
+
+static int write_adts_muxed_data(void *opaque, uint8_t *adts_data, int size)
+{
+FILE *encoded_audio_file = (FILE *)opaque;
+fwrite(adts_data, 1, size, encoded_audio_file); //(f)
+return size;
+}
+
+static int mux_aac_packet_to_adts (AVPacket *encoded_audio_packet, 
AVFormatContext *adts_container_ctx)
+{
+int ret_val;
+if ((ret_val = av_write_frame(adts_container_ctx, encoded_audio_packet)) < 
0) {
+av_log(NULL, AV_LOG_ERROR, "Error calling av_write_frame() (error 
'%s')\n", av_err2str(ret_val));
+}
+else {
+av_log(NULL, AV_LOG_INFO, "Encoded AAC packet %d, size=%d, 
pts_time=%s\n", 
+   encoded_pkt_counter, encoded_audio_packet->size, 
+   av_ts2timestr(encoded_audio_packet->pts, 
&adts_container_ctx->streams[0]->time_base));
+}
+return ret_val;
+}
+
+static int check_if_samplerate_is_supported(AVCodec *audio_codec, int 
samplerate)
+{
+const int *samplerates_list = audio_codec->supported_samplerates;
+while (*samplerates_list) {
+if (*samplerates_list == samplerate)
+return 0;
+samplerates_list++;  
+}
+return 1;
+}
+
+int main(int argc, char **argv)
+{
+FILE *input_audio_file = NULL, *encoded_audio_file = NULL;
+AVCodec *audio_codec = NULL;
+AVCodecContext *audio_encoder_ctx = NULL;
+AVFrame *input_audio_frame = NULL, *converted_audio_frame = NULL;
+SwrContext *audio_convert_context = NULL;
+AVOutputFormat *adts_container = NULL;
+AVFormatContext *adts_container_ctx = NULL;
+uint8_t *adts_container_buffer = NULL;
+size_t adts_container_buffer_size = 4096;
+AVIOContext *adts_avio_ctx = NULL;
+AVStream *adts_stream = NULL;  
+AVPacket *encoded_audio_packet = NULL;
+int ret_val = 0;
+int audio_bytes_to_encode;
+int64_t curr_pts;
+
+if (argc != 2) {
+printf("Usage: %s \n", argv[0]);
+return 1;
+}
+
+

[FFmpeg-devel] [PATCH] New API usage example (encode_raw_audio_file_to_aac)

2017-03-31 Thread Paolo Prete
filter_audio
diff --git a/doc/examples/Makefile b/doc/examples/Makefile
index 2d0a306..24929e3 100644
--- a/doc/examples/Makefile
+++ b/doc/examples/Makefile
@@ -17,6 +17,7 @@ EXAMPLES=   avio_dir_cmd   \
 decode_video   \
 demuxing_decoding  \
 encode_audio   \
+encode_raw_audio_file_to_aac   \
 encode_video   \
 extract_mvs\
 filtering_video\
diff --git a/doc/examples/encode_raw_audio_file_to_aac.c 
b/doc/examples/encode_raw_audio_file_to_aac.c
new file mode 100644
index 000..5e6df5c
--- /dev/null
+++ b/doc/examples/encode_raw_audio_file_to_aac.c
@@ -0,0 +1,338 @@
+/*
+ * Copyright (c) 2017 Paolo Prete (p4olo_pr...@yahoo.it)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to 
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/**
+ * @file
+ * API example for adts-aac encoding raw audio files. 
+ * This example reads a raw audio input file, converts it to float-planar 
format, performs 
+ * aac encoding and puts the encoded frames into an ADTS container. 
+ * The encoded stream is written to a file named "out.aac"
+ * It can be adapted, with few changes, to a custom raw audio source (i.e: a 
live one). 
+ * It uses a custom I/O write callback (write_adts_muxed_data()) in order to 
show to the user 
+ * how to access muxed packets written in memory, before they are written to 
the output file.
+ * The raw input audio file can be created with: 
+ * 
+ * ffmpeg -i some_audio_file -f f32le -acodec pcm_f32le -ac 2 -ar 16000 
raw_audio_file.raw
+ * 
+ * @example encode_raw_audio_file_to_aac.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#define ENCODER_BITRATE 64000
+#define SAMPLE_RATE 16000
+#define INPUT_SAMPLE_FMT AV_SAMPLE_FMT_FLT
+#define CHANNELS 2
+
+static int encoded_pkt_counter = 1;
+
+static int write_adts_muxed_data(void *opaque, uint8_t *adts_data, int size)
+{
+FILE *encoded_audio_file = (FILE *)opaque;
+fwrite(adts_data, 1, size, encoded_audio_file); //(f)
+return size;
+}
+
+static int mux_aac_packet_to_adts (AVPacket *encoded_audio_packet, 
AVFormatContext *adts_container_ctx)
+{
+int ret_val;
+if ((ret_val = av_write_frame(adts_container_ctx, encoded_audio_packet)) < 
0) {
+av_log(NULL, AV_LOG_ERROR, "Error calling av_write_frame() (error 
'%s')\n", av_err2str(ret_val));
+}
+else {
+av_log(NULL, AV_LOG_INFO, "Encoded AAC packet %d, size=%d, 
pts_time=%s\n", 
+   encoded_pkt_counter, encoded_audio_packet->size, 
+   av_ts2timestr(encoded_audio_packet->pts, 
&adts_container_ctx->streams[0]->time_base));
+}
+return ret_val;
+}
+
+static int check_if_samplerate_is_supported(AVCodec *audio_codec, int 
samplerate)
+{
+const int *samplerates_list = audio_codec->supported_samplerates;
+while (*samplerates_list) {
+if (*samplerates_list == samplerate)
+return 0;
+samplerates_list++;  
+}
+return 1;
+}
+
+int main(int argc, char **argv)
+{
+FILE *input_audio_file = NULL, *encoded_audio_file = NULL;
+AVCodec *audio_codec = NULL;
+AVCodecContext *audio_encoder_ctx = NULL;
+AVFrame *input_audio_frame = NULL, *converted_audio_frame = NULL;
+SwrContext *audio_convert_context = NULL;
+AVOutputFormat *adts_container = NULL;
+AVFormatContext *adts_container_ctx = NULL;
+uint8_t *adts_container_buffer = NULL;
+size_t adts_container_buffer_size = 4096;
+AVIOContext *adts_avio_ctx = NULL;
+AVStream *adts_stream = NULL;  
+AVPacket *encoded_audio_packet = NULL;
+int ret_val = 0;
+int audio_bytes_to_encode;
+int64_t curr_pts;
+
+if (argc != 2) {
+printf("Usage: %s \n", argv[0])

[FFmpeg-devel] [PATCH] doc/examples/muxing: code rewrite with improved readability and fixed issues

2022-06-18 Thread Paolo Prete
Please review this. It's a code rewrite of doc/examples/muxing.c which improves 
readability and fixes issues.
More specifically:
*) Original functions of muxing.c have generic/unclear/ambiguous names and they 
don't group logically relatedblocks of code: this makes the code hard to 
read.See for example open_audio/video() and add_stream(), which mix 
initialization of the encoders' and muxers' stuff.A redundant structure with an 
ambiguous name ("struct OutputStream"), which is not part of API, is widely 
used too.The patch uses functions with clearer names and with blocks of code 
strictly logically related, such as: init_encoder(), init_avframe(), 
init_muxer(), convert_frame(), encode_frame(), mux_encoded_pkt()...
*) Errors are not always properly managed: in some cases they are not 
propagated to the main() function and a call to exit(1) is forced, causing 
memory leaks. This has been fixed as well.
*) The program doesn't work for some extensions (try for example: m4v or 
mjpeg). In addition, it gives weird results when the filename doesn't have an 
extension.This has been fixed by checking the filename and supporting a fixed 
set of extensions.
*) The program claims to output raw images by using '%%d' in the filename, but 
it actually doesn't. This has been fixed as well.
*) Input parameters such as width, height, sample_rate and ch_layout are now 
exposed at the level of the main() function and they are much easier to 
customize.
*) fprintf() has been replaced with av_log()
From 8a4e942a001ae49dc052899f331ed43abf954dda Mon Sep 17 00:00:00 2001
From: paolo 
Date: Sat, 18 Jun 2022 13:53:55 +0200
Subject: [PATCH] doc/examples/muxing: code rewrite with improved readability
 and fixed issues

   Improved readability with functions that have clearer prototypes and that don't mix logically unrelated blocks of code

   Fixed issues in case of unsupported extensions

   Fixed memory leaks on errors, which are now properly propagated to the main() function

   Fixed issue on raw images output

   fprintf() replaced with av_log()

   Input A/V parameters exposed in the main() function and easier to customize
---
 doc/examples/muxing.c | 905 +++---
 1 file changed, 406 insertions(+), 499 deletions(-)

diff --git a/doc/examples/muxing.c b/doc/examples/muxing.c
index 3acb778322..04739995d8 100644
--- a/doc/examples/muxing.c
+++ b/doc/examples/muxing.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003 Fabrice Bellard
+ * Copyright (c) 2022 Paolo Prete (paolopr976 at gmail.com) after Fabrice Bellard
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -24,625 +24,532 @@
  * @file
  * libavformat API example.
  *
- * Output a media file in any supported libavformat format. The default
+ * Output a media file in a set of supported libavformat formats. The default
  * codecs are used.
  * @example muxing.c
  */
 
-#include 
-#include 
-#include 
-#include 
-
-#include 
-#include 
-#include 
-#include 
-#include 
 #include 
 #include 
-#include 
+#include 
 #include 
+#include 
 
-#define STREAM_DURATION   10.0
-#define STREAM_FRAME_RATE 25 /* 25 images/s */
-#define STREAM_PIX_FMTAV_PIX_FMT_YUV420P /* default pix_fmt */
-
-#define SCALE_FLAGS SWS_BICUBIC
+#define VIDEO_FRAME_RATE 25 /* 25 images/s */
+#define VIDEO_SCALE_FLAGS SWS_BICUBIC
+#define STREAM_DURATION 10.0 /* 10 seconds */
 
-// a wrapper around a single output AVStream
-typedef struct OutputStream {
-AVStream *st;
-AVCodecContext *enc;
+static void log_error(const char *s, int *num)
+{
+if (num)
+av_log(NULL, AV_LOG_ERROR, "%s (error '%s')\n", s, av_err2str(*num));
+else
+av_log(NULL, AV_LOG_ERROR, "%s\n", s);
+}
 
-/* pts of the next frame that will be generated */
-int64_t next_pts;
-int samples_count;
+static int mux_encoded_pkt(AVPacket *out_pkt, AVFormatContext *out_fmt_ctx,
+  enum AVMediaType type)
+{
+int ret;
+AVRational enc_time_base, str_time_base;
 
-AVFrame *frame;
-AVFrame *tmp_frame;
+if (out_fmt_ctx->streams[0]->codecpar->codec_type == type)
+out_pkt->stream_index = 0;
+else if ((out_fmt_ctx->nb_streams > 1) && (type == AVMEDIA_TYPE_VIDEO))
+out_pkt->stream_index = 1;
+str_time_base = out_fmt_ctx->streams[out_pkt->stream_index]->time_base;
 
-AVPacket *tmp_pkt;
+if (type == AVMEDIA_TYPE_AUDIO)
+enc_time_base = ((AVRational *)out_fmt_ctx->opaque)[0];
+else
+enc_time_base = ((AVRational *)out_fmt_ctx->opaque)[1];
 
-float t, tincr, tincr2;
+av_packet_rescale_ts(out_pkt, enc_time_base, str_time_base);
 
-struc

Re: [FFmpeg-devel] [PATCH] doc/examples/muxing: code rewrite with improved readability and fixed issues

2022-06-18 Thread Paolo Prete
 

Il sabato 18 giugno 2022, 17:18:18 CEST, Leo Izen  ha 
scritto:

>>On 6/18/22 08:06, Paolo Prete wrote:>> +{>> +    if (num)>> +        
>>av_log(NULL, AV_LOG_ERROR, "%s (error '%s')\n", s, av_err2str(*num));>> +    
>>else>> +        av_log(NULL, AV_LOG_ERROR, "%s\n", s);> +}>This does not need 
>>to be a pointer. Convention is that negative values>are errors and 
>>nonnegative values are not. So you could always use>something like: if (num < 
>>0).
The pointer makes clearer, when I call the function, that I'm not managing a 
specific error with a number id.
>> -    AVPacket *tmp_pkt;>> +    if (type == AVMEDIA_TYPE_AUDIO)>> +        
>> enc_time_base = ((AVRational *)out_fmt_ctx->opaque)[0];>> +    else>> +      
>>   enc_time_base = ((AVRational *)out_fmt_ctx->opaque)[1];>>>Why are you 
>> referencing the opaque elements of out_fmt_ctx?
I pass, through the opaque element, user data to the muxer. That data (the 
timebases of the audio and video encoders) will be used for rescaling ts to 
themuxer timebases. Otherwise I would have to pass them through the function's 
params, which would make the function prototype longer and less readable.
>>>> -static int write_frame(AVFormatContext *fmt_ctx, AVCodecContext *c,>> -   
>>>>                    AVStream *st, AVFrame *frame, AVPacket *pkt)>> +static 
>>>> int is_extension_supported(const char *filename)>Why are you artificially 
>>>> limiting what is permitted?
>From what I see, not all extensions are supported without modifying the 
>default settings. In fact, as specified in the commit msg, some extensions 
>don't work and the original muxing.c fails with them.

>> +    if (!(c = avcodec_find_encoder(id))) {>> +        
>> avformat_free_context(tmp_fctx);>> +        return ret;>You probably don't 
>> want to return "ret" here as you don't assign it.
ret is assigned to 0 (= success) at the definition of the variable. And in this 
case, the function succeeds: the returned AVCodecParameter is set with 
AV_CODEC_ID_NONE

>> -    if (oc->oformat->flags & AVFMT_GLOBALHEADER)>> -        c->flags |= 
>> AV_CODEC_FLAG_GLOBAL_HEADER;>> +    return ret;> Again, why are you 
>> returning ret if you are not assigning to it?
as above, ret is assigned to 0.
>> +    codec = avcodec_find_encoder(params->codec_id);>> +    *enc_ctx = 
>> avcodec_alloc_context3(codec);>Don't attempt to allocate anything until 
>> after you check if the codec is>found.
Is it really necessary?It has been already checked in the line with "if 
(process_audio/video) {" and the API doxy says that a NULL parameter will only 
cause that codec-specific defaults won't be initialized (so  it appears safe to 
me).
>> +    if (!codec) {>> +        log_error("Could not allocate the encoding 
>> context", NULL);>This error message does not match the check, which is if 
>> the codec is found.>> +        return AVERROR_EXIT;>return 
>> AVERROR_CODEC_NOT_FOUND;
Instead of changing the error msg, I think that what was wrong is the check. I 
fixed it withif (!(*enc_ctx = avcodec_alloc_context3(codec))) {
>> +        (*enc_ctx)->sample_rate = params->sample_rate;>> +        
>> (*enc_ctx)->time_base  = (AVRational){1, params->sample_rate};>Use av_make_q 
>> to avoid casting.
Done, thanks.
> +        return ret;> +    } else> +        return 0;This violates the coding 
> style, you need to use braces {} for the elseblock if you also use it for the 
> if block.
Done, thanks.
> +    if ((ret = av_frame_get_buffer(*frame, 0)) < 0) {> +        
> log_error("Could not allocate buffer for AVFrame", &ret);> +        return 
> AVERROR(ENOMEM);> +    } else> +        return 0;You don't need the else 
> block here at all.
Done, thanks.
>> +static int init_video_convert(struct SwsContext **ctx, AVCodecParameters 
>> *in_params,>> +                              AVCodecParameters 
>> *out_params)>> +{>This paper-thin wrapper function is unnecessary, just 
>> inline it.
This is intentional: even if it's a paper-thin wrapper, it shortens the code of 
the main() functionby making it quicker to understand that the audio/video 
converters are initialized with their respective AVCodecParameters. I would 
wait for feedback about this from other readers, before changing the code.
> +> +    if (!tincr) {> +        t      = 0;> +        tincr  = 2 * M_PI * 
> 110.0 / frame->sample_rate;> +        /* increment 

Re: [FFmpeg-devel] [PATCH] doc/examples/muxing: code rewrite with improved readability and fixed issues

2022-06-18 Thread Paolo Prete
 

Il sabato 18 giugno 2022, 19:07:11 CEST, Andreas Rheinhardt 
 ha scritto:  
 
 >>Paolo Prete:
>> Please review this. It's a code rewrite of doc/examples/muxing.c which 
>> improves readability and fixes issues.
>> More specifically:
>> *) Original functions of muxing.c have generic/unclear/ambiguous names and 
>> they don't group logically relatedblocks of >>code: this makes the code hard 
>> to read.See for example open_audio/video() and add_stream(), which mix 
>> initialization of >>the encoders' and muxers' stuff.A redundant structure 
>> with an ambiguous name ("struct OutputStream"), which is not part of >>API, 
>> is widely used too.The patch uses functions with clearer names and with 
>> blocks of code strictly logically related, such >>as: init_encoder(), 
>> init_avframe(), init_muxer(), convert_frame(), encode_frame(), 
>> mux_encoded_pkt()...

>Using a structure for the user's data is actually intentional, because
>users will probably use one, too. And given that it is the user's
>structure it is of course not part of the public API.
This is not what I meant. The API already has all the needed structures for 
managing, by the user, all the flow of an A/V pipeline. There's no need of 
another struct (which is therefore redundant and with a meaningless name) for 
exchanging data between functions. Please consider the code of the patch in a 
different perspective. It explicitly, in the main() function, creates an 
encoder, a converter and a muxer and the required input/output frames: nothing 
more, nothing else. And it simply calls fill_frame(), convert_frame(), 
encode_frame(), mux_encoded_pkt(). This is what I suggest as a readable code 
which represents an A/V pipeline. These function have names that represent 
exactly what they do, instead of using generic/misleading names such as 
"open_audio()" or "write_frame()" etc. For doing that I had to rewrite the code 
from scratch, then it's not possible to split the patch into small pieces, as 
you ask.


> There is just one thing that I immediately noticed:
>
>
> sizeof(AVCodecParameters) is not public, you must not put
> AVCodecParameters on the stack.

i just fixed this, thanks. See the attached patch in response to Leo Izen


  
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH] doc/examples/muxing: code rewrite with improved readability and fixed issues

2022-06-18 Thread Paolo Prete
Sorry: I had problems with my email client in formatting the previous message. 
I just try to resend it.

>> Il sabato 18 giugno 2022, 17:18:18 CEST, Leo Izen  ha 
>> scritto:
>>On 6/18/22 08:06, Paolo Prete wrote:
>> +{
>> +    if (num)
>> +        av_log(NULL, AV_LOG_ERROR, "%s (error '%s')\n", s, 
>> av_err2str(*num));
>> +    else
>> +        av_log(NULL, AV_LOG_ERROR, "%s\n", s);
> +}
>This does not need to be a pointer. Convention is that negative values
>are errors and nonnegative values are not. So you could always use
>something like: if (num < 0).

The pointer makes clearer, when I call the function, that I'm not managing an 
error with a number id.

>> -    AVPacket *tmp_pkt;
>> +    if (type == AVMEDIA_TYPE_AUDIO)
>> +        enc_time_base = ((AVRational *)out_fmt_ctx->opaque)[0];
>> +    else
>> +        enc_time_base = ((AVRational *)out_fmt_ctx->opaque)[1];
>>
>Why are you referencing the opaque elements of out_fmt_ctx?

I pass, through the opaque element, user data to the muxer. That data (the 
timebases of the audio and video encoders) will be used for rescaling ts to the
muxer timebases. Otherwise I would have to pass them through the function's 
params, which would make the function prototype longer and less readable.

>>
>> -static int write_frame(AVFormatContext *fmt_ctx, AVCodecContext *c,
>> -                      AVStream *st, AVFrame *frame, AVPacket *pkt)
>> +static int is_extension_supported(const char *filename)
>Why are you artificially limiting what is permitted?

>From what I see, not all extensions are supported without modifying the 
>default settings. In fact, as specified in the commit msg, some extensions 
>don't work and the original muxing.c fails with them.

>> +    if (!(c = avcodec_find_encoder(id))) {
>> +        avformat_free_context(tmp_fctx);
>> +        return ret;
>You probably don't want to return "ret" here as you don't assign it.

ret is assigned to 0 (= success) at the definition of the variable. And in this 
case, the function succeeds: the returned AVCodecParameter is set with 
AV_CODEC_ID_NONE

>> -    if (oc->oformat->flags & AVFMT_GLOBALHEADER)
>> -        c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
>> +    return ret;
> Again, why are you returning ret if you are not assigning to it?

as above, ret is assigned to 0.

>> +    codec = avcodec_find_encoder(params->codec_id);
>> +    *enc_ctx = avcodec_alloc_context3(codec);
>Don't attempt to allocate anything until after you check if the codec is
>found.

Is it really necessary?
It has been already checked in the line with "if (process_audio/video) {" and 
the API doxy says that a NULL parameter will only cause that codec-specific 
defaults won't be initialized (so  it appears safe to me).

>> +    if (!codec) {
>> +        log_error("Could not allocate the encoding context", NULL);
>This error message does not match the check, which is if the codec is found.
>> +        return AVERROR_EXIT;
>return AVERROR_CODEC_NOT_FOUND;

Instead of changing the error msg, I think that what was wrong is the check. I 
fixed it with
if (!(*enc_ctx = avcodec_alloc_context3(codec))) {

>> +        (*enc_ctx)->sample_rate = params->sample_rate;
>> +        (*enc_ctx)->time_base  = (AVRational){1, params->sample_rate};
>Use av_make_q to avoid casting.

Done, thanks.

> +        return ret;
> +    } else
> +        return 0;This violates the coding style, you need to use braces {} 
> for the else
block if you also use it for the if block.

Done, thanks.

> +    if ((ret = av_frame_get_buffer(*frame, 0)) < 0) {
> +        log_error("Could not allocate buffer for AVFrame", &ret);
> +        return AVERROR(ENOMEM);
> +    } else
> +        return 0;
You don't need the else block here at all.

Done, thanks.

>> +static int init_video_convert(struct SwsContext **ctx, AVCodecParameters 
>> *in_params,
>> +                              AVCodecParameters *out_params)
>> +{
>This paper-thin wrapper function is unnecessary, just inline it.

This is intentional: even if it's a paper-thin wrapper, it shortens the code of 
the main() function
by making it quicker to understand that the audio/video converters are 
initialized with their respective AVCodecParameters. I would wait for feedback 
about this from other readers, before changing the code.

> +
> +    if (!tincr) {
> +        t      = 0;
> +        tincr  = 2 * M_PI * 110.0 / frame->sample_rate;
> +        /* increment frequency by 110 Hz per second */
> +        tincr2  = tincr / frame->sample_rate;
> Wh

[FFmpeg-devel] [PATCH v2] doc/examples/muxing: code rewrite with improved readability and fixed issues

2022-06-20 Thread Paolo Prete
Please review it!

Difference to v1:

*) AVCodecParameter(s) allocated with avcodec_parameters_alloc()
*) AVRational  objects created with av_make_q() (in the original muxing.c they 
are created through a cast to AVRational)
*) removed unuseful "else"s
*) fixed error check in case of avcodec_alloc_context3() failsFrom 2e9cc74d3a8b637d8adff5d78632cf1321d7e2cf Mon Sep 17 00:00:00 2001
From: paolo 
Date: Mon, 20 Jun 2022 20:56:47 +0200
Subject: [PATCH v2] doc/examples/muxing: code rewrite with improved
 readability and fixed issues

   Improved readability with functions that have clearer prototypes and that don't mix logically unrelated blocks of code

   Fixed issues in case of unsupported extensions

   Fixed memory leaks on errors, which are now properly propagated to the main() function

   Fixed issue on raw images output

   fprintf() replaced with av_log()

   Input A/V parameters exposed in the main() function and easier to customize
---
 doc/examples/muxing.c | 919 +++---
 1 file changed, 423 insertions(+), 496 deletions(-)

diff --git a/doc/examples/muxing.c b/doc/examples/muxing.c
index 3acb778322..a91134ac7c 100644
--- a/doc/examples/muxing.c
+++ b/doc/examples/muxing.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2003 Fabrice Bellard
+ * (Code rewrite by Paolo Prete, 2022)
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -24,625 +25,551 @@
  * @file
  * libavformat API example.
  *
- * Output a media file in any supported libavformat format. The default
+ * Output a media file in a set of supported libavformat formats. The default
  * codecs are used.
  * @example muxing.c
  */
 
-#include 
-#include 
-#include 
-#include 
-
-#include 
-#include 
-#include 
-#include 
-#include 
 #include 
 #include 
-#include 
+#include 
 #include 
+#include 
 
-#define STREAM_DURATION   10.0
-#define STREAM_FRAME_RATE 25 /* 25 images/s */
-#define STREAM_PIX_FMTAV_PIX_FMT_YUV420P /* default pix_fmt */
-
-#define SCALE_FLAGS SWS_BICUBIC
+#define VIDEO_FRAME_RATE 25 /* 25 images/s */
+#define VIDEO_SCALE_FLAGS SWS_BICUBIC
+#define STREAM_DURATION 10.0 /* 10 seconds */
 
-// a wrapper around a single output AVStream
-typedef struct OutputStream {
-AVStream *st;
-AVCodecContext *enc;
+static void log_error(const char *s, int *num)
+{
+if (num)
+av_log(NULL, AV_LOG_ERROR, "%s (error '%s')\n", s, av_err2str(*num));
+else
+av_log(NULL, AV_LOG_ERROR, "%s\n", s);
+}
 
-/* pts of the next frame that will be generated */
-int64_t next_pts;
-int samples_count;
+static int mux_encoded_pkt(AVPacket *out_pkt, AVFormatContext *out_fmt_ctx,
+  enum AVMediaType type)
+{
+int ret;
+AVRational enc_time_base, str_time_base;
 
-AVFrame *frame;
-AVFrame *tmp_frame;
+if (out_fmt_ctx->streams[0]->codecpar->codec_type == type)
+out_pkt->stream_index = 0;
+else if ((out_fmt_ctx->nb_streams > 1) && (type == AVMEDIA_TYPE_VIDEO))
+out_pkt->stream_index = 1;
+str_time_base = out_fmt_ctx->streams[out_pkt->stream_index]->time_base;
 
-AVPacket *tmp_pkt;
+if (type == AVMEDIA_TYPE_AUDIO)
+enc_time_base = ((AVRational *)out_fmt_ctx->opaque)[0];
+else
+enc_time_base = ((AVRational *)out_fmt_ctx->opaque)[1];
 
-float t, tincr, tincr2;
+av_packet_rescale_ts(out_pkt, enc_time_base, str_time_base);
 
-struct SwsContext *sws_ctx;
-struct SwrContext *swr_ctx;
-} OutputStream;
+av_log(NULL, AV_LOG_INFO, "stream_index=%d, size=%d, pts_time=%s\n",
+   out_pkt->stream_index,
+   out_pkt->size, av_ts2timestr(out_pkt->pts, &str_time_base));
 
-static void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt)
-{
-AVRational *time_base = &fmt_ctx->streams[pkt->stream_index]->time_base;
+if ((ret = av_interleaved_write_frame(out_fmt_ctx, out_pkt)) < 0)
+log_error("Error calling av_interleaved_write_frame()", &ret);
 
-printf("pts:%s pts_time:%s dts:%s dts_time:%s duration:%s duration_time:%s stream_index:%d\n",
-   av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, time_base),
-   av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, time_base),
-   av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, time_base),
-   pkt->stream_index);
+return ret;
 }
 
-static int write_frame(AVFormatContext *fmt_ctx, AVCodecContext *c,
-   AVStream *st, AVFrame *frame, AVPacket *pkt)
+static int is_extension_supported(const char *filename)
 {
-int ret;
-
-// send the frame to the encoder
-ret = avcodec_send_fr

[FFmpeg-devel] [PATCH] New API usage example (reading, converting, encoding and muxing an audio file)

2022-06-06 Thread Paolo Prete
-$(CONFIG_MUXING_EXAMPLE)   += muxing
+EXAMPLES-$(CONFIG_QSVDEC_EXAMPLE)   += qsvdec
+EXAMPLES-$(CONFIG_REMUXING_EXAMPLE) += remuxing
+EXAMPLES-$(CONFIG_RESAMPLING_AUDIO_EXAMPLE) += resampling_audio
+EXAMPLES-$(CONFIG_SCALING_VIDEO_EXAMPLE)+= scaling_video
+EXAMPLES-$(CONFIG_TRANSCODE_AAC_EXAMPLE)+= transcode_aac
+EXAMPLES-$(CONFIG_TRANSCODING_EXAMPLE)  += transcoding
+EXAMPLES-$(CONFIG_VAAPI_ENCODE_EXAMPLE) += vaapi_encode
+EXAMPLES-$(CONFIG_VAAPI_TRANSCODE_EXAMPLE)  += vaapi_transcode
 
 EXAMPLES   := $(EXAMPLES-yes:%=doc/examples/%$(PROGSSUF)$(EXESUF))
 EXAMPLES_G := $(EXAMPLES-yes:%=doc/examples/%$(PROGSSUF)_g$(EXESUF))
diff --git a/doc/examples/Makefile.example b/doc/examples/Makefile.example
index a232d97f98..f2438caeb8 100644
--- a/doc/examples/Makefile.example
+++ b/doc/examples/Makefile.example
@@ -13,6 +13,7 @@ LDLIBS := $(shell pkg-config --libs $(FFMPEG_LIBS)) $(LDLIBS)
 
 EXAMPLES=   avio_list_dir  \
 avio_reading   \
+convert_encode_mux_audio   \
 decode_audio   \
 decode_video   \
 demuxing_decoding  \
diff --git a/doc/examples/convert_encode_mux_audio.c b/doc/examples/convert_encode_mux_audio.c
new file mode 100644
index 00..abde611bf6
--- /dev/null
+++ b/doc/examples/convert_encode_mux_audio.c
@@ -0,0 +1,351 @@
+/*
+ * Copyright (c) 2019 Paolo Prete (paolopr976 at gmail.com)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/**
+ * @file
+ * API example for converting, encoding and muxing raw audio files.
+ * This example reads a raw audio input file, converts it to a sample format accepted by
+ * a given encoder, performs encoding and puts the encoded frames into a muxing container.
+ * The encoded stream is written to a file named "outfile".
+ * It can be adapted, with few changes, to a custom raw audio source (i.e: a live one).
+ * It uses a custom I/O write callback (write_muxed_data()) in order to show how to access
+ * muxed packets written in memory, before they are written to the output file.
+ *
+ * The raw input audio file can be created with:
+ *
+ * ffmpeg -i some_audio_file -f f32le -acodec pcm_f32le -ac 2 -ar 48000 raw_audio_file.raw
+ *
+ * @example convert_encode_mux_audio.c
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+// Customizable parameters
+#define SAMPLE_RATE 48000
+#define ENCODER_ID AV_CODEC_ID_AAC
+#define ENCODER_BITRATE 64000
+#define INPUT_SAMPLE_FMT AV_SAMPLE_FMT_FLT
+#define OUTPUT_SAMPLE_FMT AV_SAMPLE_FMT_FLTP
+#define INPUT_CHANNELS 2
+#define OUTPUT_CHANNELS 2
+
+static int encoded_pkt_counter = 1;
+
+static int write_muxed_data(void *opaque, uint8_t *data, int size)
+{
+FILE *encoded_audio_file = (FILE *)opaque;
+fwrite(data, 1, size, encoded_audio_file); //(h)
+return size;
+}
+
+static int mux_encoded_packet(AVPacket *encoded_audio_packet, AVFormatContext *out_container_ctx)
+{
+int ret_val;
+if ((ret_val = av_write_frame(out_container_ctx, encoded_audio_packet)) < 0) {
+av_log(NULL, AV_LOG_ERROR, "Error calling av_write_frame() (error '%s')\n", av_err2str(ret_val));
+} else {
+av_log(NULL, AV_LOG_INFO, "Encoded packet %d, size=%d, pts_time=%s\n",
+   encoded_pkt_counter, encoded_audio_packet->size,
+   av_ts2timestr(encoded_audio_packet->pts, &out_container_ctx->streams[0]->time_base));
+}
+return ret_val;
+}
+
+static int check_if_samplerate_is_supported(const AVCodec *audio_codec, int samplerate)
+{
+const int *samplerates_list = audio_codec->supported_samplerates;
+while (*samplerates_list) {
+if (*samplerates_list == samplerate)
+

Re: [FFmpeg-devel] [PATCH] New API usage example (reading, converting, encoding and muxing an audio file)

2022-06-07 Thread Paolo Prete
What you say is true, IMHO, as long as the functions (in which the code is 
split) do really group logically related tasks and they have names that 
summarize what they are doing. In the examined case this is not true, see for 
example (in muxing.c):
static void open_video(AVFormatContext *oc, const AVCodec *codec, OutputStream 
*ost, AVDictionary *opt_arg)

The name "open_video" is too generic and it doesn't let the user know what the 
function is actually doing, without jumping from line to line in the code. In 
fact the function mixes different tasks: it opens the codec, it allocates a 
frame, it copies the stream parameters to the muxer. Same thing for 
write_audio_frame(), and in fact a comment is put just above the function, and 
it says:
"encode one audio frame and send it to the muxer,,,"
...which is obscure from the function's name (and, again, the user is forced to 
jump often from a chunk to another chunk of code in order to understand what 
the code is _generally_ doing).Note too that this can't be fixed by using more 
explicative or longer names, because the functions mixes tasks which are 
_different_.
Therefore, these functions in many cases do not improve readability and IMHO is 
better to have a longer code instead of forcing grouping different tasks in the 
same function with an ambiguous name.



   Il martedì 7 giugno 2022, 11:42:23 CEST, Anton Khirnov  
ha scritto:  
 
 Quoting Paolo Prete (2022-06-06 19:40:42)
> Hello,
> From what I see, the doc/examples files can be still improved. More
> precisely, their main() is often split into functions with short names
> that hide important (sometime essential) details of what they're doing
> and they worsen the readability, by forcing the user to jump from
> chunks to chunks of the code.

I disagree VERY strongly.

Long functions are extremely hard to reason about, because of all the
pieces you have to keep in your head at once. Grouping logically related
blocks of code into their own small functions that can be thought of as
a single unit immensely improves readability and maintainability.

-- 
Anton Khirnov
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
  
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".


Re: [FFmpeg-devel] [PATCH] New API usage example (reading, converting, encoding and muxing an audio file)

2022-06-07 Thread Paolo Prete
 

Il martedì 7 giugno 2022, 13:56:37 CEST, Anton Khirnov  
ha scritto:  
 
 >Quoting Paolo Prete (2022-06-07 12:59:05)
>> What you say is true, IMHO, as long as the functions (in which the
>> code is split) do really group logically related tasks and they have
>> names that summarize what they are doing. In the examined case this is
>> not true, see for example (in muxing.c): static void
>> open_video(AVFormatContext *oc, const AVCodec *codec, OutputStream
>> *ost, AVDictionary *opt_arg)
>> 
>> The name "open_video" is too generic and it doesn't let the user know
>> what the function is actually doing, without jumping from line to line
>> in the code. In fact the function mixes different tasks: it opens the
>> codec, it allocates a frame, it copies the stream parameters to the
>> muxer.

>All the things it does relate to preparing video encoding. You might
>argue that the function name is suboptimal, in which case it should be
>improved. But it is certainly not true that the function just groups
>random unrelated code.

Not true. There's a step, inside the function, that does _not_ relate to 
preparing video encoding, then it should not be grouped into the same logical 
unit: 
    /* copy the stream parameters to the muxer */    ret = 
avcodec_parameters_from_context(ost->st->codecpar, c);
Then: how would you call the function? Obviously, "prepare_video_encoding()" 
would not be appropriate.

>> Same thing for write_audio_frame(), and in fact a comment is
>> put just above the function, and it says: "encode one audio frame and
>> send it to the muxer,,," ...which is obscure from the function's name
>> (and, again, the user is forced to jump often from a chunk to another
>> chunk of code in order to understand what the code is _generally_
>> doing).Note too that this can't be fixed by using more explicative or
>> longer names, because the functions mixes tasks which are _different_.
>> Therefore, these functions in many cases do not improve readability
>> and IMHO is better to have a longer code instead of forcing grouping
>> different tasks in the same function with an ambiguous name.

>Your argument seems to amount to "the existing structure is imperfect,
>so it is better to have no structure at all", 
Avoiding to split code, when not so useful, doesn't mean to "have no structure 
at all".The code I pasted has its own precise structure. 
with which I disagree.
>And even if you convinced me, adding a whole new example while keeping
>the old one is not a good solution - people would just be confused by
>multiple examples doing the same thing in different ways.
The new example doesn't do the same thing in different ways. In fact:
1) It reads from file, with customizable params (sample rate, sample fmt, 
channels ...) and not from a dummy generated audio. 2) It uses a custom I/O 
callback for accessing muxed data3) it operates on audio only.
You could argue that some tasks are already inside muxing.c, but this applies 
to encode_audio.c too. And having encode_audio.c + muxing.c doesn't confuse 
people IMHO.


  
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".