Re: [FFmpeg-devel] [PATCH 4/5] aptx: implement the aptX HD bluetooth codec
On Tue, Jan 9, 2018 at 5:07 AM, Rostislav Pehlivanov wrote: > >> Anyway, all this discussion is moot as Hendrik pointed out that profile >> can't be set outside of lavc to determine a decoder behavior. >> > > What, based on a comment in lavc? Comments there describe the api but they > rarely define it. We're free to adjust them if need be and in this case, > since the codec profile may not be set, the API user is forced to deal with > the lack of such set. Hence, we can clarify that it may be set by lavf as > well as lavc as well as not being set at all. And the decoder may use it. > I maintain that adding a new codec ID for this is unacceptable. > We already have established methods to select codec sub-variants, we don't need to invent a new one just because you feel like it. - Hendrik ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH v2 1/1] avformat/hlsenc: closed caption tags in the master playlist
From: Vishwanath Dixit --- doc/muxers.texi | 37 +++ libavformat/dashenc.c | 2 +- libavformat/hlsenc.c | 155 +- libavformat/hlsplaylist.c | 5 +- libavformat/hlsplaylist.h | 3 +- 5 files changed, 197 insertions(+), 5 deletions(-) diff --git a/doc/muxers.texi b/doc/muxers.texi index b060c4f..d9a5cc0 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -901,6 +901,43 @@ and they are mapped to the two video only variant streams with audio group names By default, a single hls variant containing all the encoded streams is created. +@item cc_stream_map +Map string which specifies different closed captions groups and their +attributes. The closed captions stream groups are separated by space. +Expected string format is like this +"ccgroup:,instreamid:,language: ". +'ccgroup' and 'instreamid' are mandatory attributes. 'language' is an optional +attribute. +The closed captions groups configured using this option are mapped to different +variant streams by providing the same 'ccgroup' name in the +@code{var_stream_map} string. If @code{var_stream_map} is not set, then the +first available ccgroup in @code{cc_stream_map} is mapped to the output variant +stream. The examples for these two use cases are given below. + +@example +ffmpeg -re -i in.ts -b:v 1000k -b:a 64k -a53cc 1 -f hls \ + -cc_stream_map "ccgroup:cc,instreamid:CC1,language:en" \ + -master_pl_name master.m3u8 \ + http://example.com/live/out.m3u8 +@end example +This example adds @code{#EXT-X-MEDIA} tag with @code{TYPE=CLOSED-CAPTIONS} in +the master playlist with group name 'cc', langauge 'en' (english) and +INSTREAM-ID 'CC1'. Also, it adds @code{CLOSED-CAPTIONS} attribute with group +name 'cc' for the output variant stream. +@example +ffmpeg -re -i in.ts -b:v:0 1000k -b:v:1 256k -b:a:0 64k -b:a:1 32k \ + -a53cc:0 1 -a53cc:1 1\ + -map 0:v -map 0:a -map 0:v -map 0:a -f hls \ + -cc_stream_map "ccgroup:cc,instreamid:CC1,language:en ccgroup:cc,instreamid:CC2,language:sp" \ + -var_stream_map "v:0,a:0,ccgroup:cc v:1,a:1,ccgroup:cc" \ + -master_pl_name master.m3u8 \ + http://example.com/live/out_%v.m3u8 +@end example +This example adds two @code{#EXT-X-MEDIA} tags with @code{TYPE=CLOSED-CAPTIONS} in +the master playlist for the INSTREAM-IDs 'CC1' and 'CC2'. Also, it adds +@code{CLOSED-CAPTIONS} attribute with group name 'cc' for the two output variant +streams. + @item master_pl_name Create HLS master playlist with the given name. diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 3345b89..39d0afe 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -820,7 +820,7 @@ static int write_manifest(AVFormatContext *s, int final) stream_bitrate += max_audio_bitrate; } get_hls_playlist_name(playlist_file, sizeof(playlist_file), NULL, i); -ff_hls_write_stream_info(st, out, stream_bitrate, playlist_file, agroup); +ff_hls_write_stream_info(st, out, stream_bitrate, playlist_file, agroup, NULL); } avio_close(out); if (use_rename) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index e36120c..4e4b287 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -145,9 +145,16 @@ typedef struct VariantStream { unsigned int nb_streams; int m3u8_created; /* status of media play-list creation */ char *agroup; /* audio group name */ +char *ccgroup; /* closed caption group name */ char *baseurl; } VariantStream; +typedef struct ClosedCaptionsStream { +char *ccgroup; /* closed caption group name */ +char *instreamid; /* closed captions INSTREAM-ID */ +char *language; /* closed captions langauge */ +} ClosedCaptionsStream; + typedef struct HLSContext { const AVClass *class; // Class for private options. int64_t start_sequence; @@ -196,11 +203,14 @@ typedef struct HLSContext { VariantStream *var_streams; unsigned int nb_varstreams; +ClosedCaptionsStream *cc_streams; +unsigned int nb_ccstreams; int master_m3u8_created; /* status of master play-list creation */ char *master_m3u8_url; /* URL of the master m3u8 file */ int version; /* HLS version */ char *var_stream_map; /* user specified variant stream map string */ +char *cc_stream_map; /* user specified closed caption streams map string */ char *master_pl_name; unsigned int master_publish_rate; int http_persistent; @@ -1115,7 +1125,8 @@ static int create_master_playlist(AVFormatContext *s, AVDictionary *options = NULL; unsigned int i, j; int m3u8_name_size, ret, bandwidth; -char *m3u8_rel_name; +char *m3u8_rel_name, *ccgroup; +ClosedCaptionsStream *ccs; input_vs->m3u8_created = 1; if (!hls->master_m3u8_created) { @@ -1142,6 +1153,16 @@ static int create_master_playlist(AVFormatContext *s, ff_hls_write_playlist_version(hls->m3u8_out, hls->ve
Re: [FFmpeg-devel] [PATCH 1/1] avformat/hlsenc: closed caption tags in the master playlist
On 12/29/17 5:35 PM, Steven Liu wrote: > 2017-12-29 19:58 GMT+08:00 Dixit, Vishwanath : >> >> On 12/29/17 5:11 PM, Steven Liu wrote: >>> 2017-12-29 18:44 GMT+08:00 : From: Vishwanath Dixit --- doc/muxers.texi | 4 libavformat/dashenc.c | 2 +- libavformat/hlsenc.c | 14 +- libavformat/hlsplaylist.c | 5 - libavformat/hlsplaylist.h | 3 ++- 5 files changed, 24 insertions(+), 4 deletions(-) diff --git a/doc/muxers.texi b/doc/muxers.texi index 93db549..8229202 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -872,6 +872,10 @@ publishing it repeatedly every after 30 segments i.e. every after 60s. @item http_persistent Use persistent HTTP connections. Applicable only for HTTP output. +@item cc_instream_id +Add @code{#EXT-X-MEDIA} tag in the master playlist with the specified instream ID. It +accepts the values in the range 1-4. + @end table @anchor{ico} diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 478a384..8797959 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -760,7 +760,7 @@ static int write_manifest(AVFormatContext *s, int final) AVStream *st = s->streams[i]; get_hls_playlist_name(playlist_file, sizeof(playlist_file), NULL, i); ff_hls_write_stream_info(st, out, st->codecpar->bit_rate, -playlist_file, NULL); +playlist_file, NULL, NULL); } avio_close(out); if (use_rename) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 74f66ce..e5176a8 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -206,6 +206,7 @@ typedef struct HLSContext { int http_persistent; AVIOContext *m3u8_out; AVIOContext *sub_m3u8_out; +int cc_instream_id; /* closed captions INSTREAM-ID */ } HLSContext; static int mkdir_p(const char *path) { @@ -1122,6 +1123,7 @@ static int create_master_playlist(AVFormatContext *s, unsigned int i, j; int m3u8_name_size, ret, bandwidth; char *m3u8_rel_name; +char cc_group[16] = {0}; input_vs->m3u8_created = 1; if (!hls->master_m3u8_created) { @@ -1148,6 +1150,14 @@ static int create_master_playlist(AVFormatContext *s, ff_hls_write_playlist_version(hls->m3u8_out, hls->version); +if (hls->cc_instream_id) { +av_strlcpy(cc_group, "group_cc", sizeof(cc_group)); >>> Why do you write "group_cc" ? maybe this can make an option be set by >>> user, and set a default string, if it can be set by user, need >>> attention with the printf, about that security. >>> >> Unlike audio rendition streams, in common usage scenarios, there will be >> only one cc rendition stream and all the video rendition streams refer to >> the same cc rendition stream. The following example shows a common use case >> where both video rendition streams (media_0.m3u8 and media_2.m3u8) are >> referring to the same closed caption rendition with group id “group_cc”. >> #EXTM3U >> #EXT-X-VERSION:3 >> >> #EXT-X-MEDIA:TYPE=CLOSED-CAPTIONS,GROUP-ID="group_cc",NAME="captions",INSTREAM-ID="CC1" >> >> #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="group_aud1",NAME="audio_0",DEFAULT=YES,URI="media_1.m3u8" >> >> #EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="group_aud2",NAME="audio_0",DEFAULT=YES,URI="media_3.m3u8" >> >> #EXT-X-STREAM-INF:BANDWIDTH=140800,RESOLUTION=1280x720,AUDIO="group_aud1",CLOSED-CAPTIONS="group_cc" >> media_0.m3u8 >> >> #EXT-X-STREAM-INF:BANDWIDTH=140800,AUDIO="group_aud1" >> media_1.m3u8 >> >> >> #EXT-X-STREAM-INF:BANDWIDTH=140800,RESOLUTION=1280x720,AUDIO="group_aud2",CLOSED-CAPTIONS="group_cc" >> media_2.m3u8 >> >> #EXT-X-STREAM-INF:BANDWIDTH=140800,AUDIO="group_aud2" >> media_3.m3u8 >> >> So, currently the group id name is fixed to “group_cc”. However, this >> functionality can be further extended in the future for different CC groups >> when there are different closed caption sources are present in the input. >> Please let me know your further thoughts/suggestions on this. > I think "group_cc" should be a variable, it can be set by the user, > not write to a constant by hlsenc. for example: > >#EXTM3U > #EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="low",NAME="Main", \ >DEFAULT=YES,URI="low/main/audio-video.m3u8" > #EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="low",NAME="Centerfield", \ >DEFAULT=NO,URI="low/centerfield/audio-video.m3u8" > #EXT-X-MEDIA:TYPE=VIDEO,GROUP-ID="low",NAME="Dugout", \ >DEFAULT=NO,UR
Re: [FFmpeg-devel] [PATCH 4/5] aptx: implement the aptX HD bluetooth codec
On Tue, Jan 9, 2018 at 9:33 AM, Hendrik Leppkes wrote: > On Tue, Jan 9, 2018 at 5:07 AM, Rostislav Pehlivanov > wrote: >> >>> Anyway, all this discussion is moot as Hendrik pointed out that profile >>> can't be set outside of lavc to determine a decoder behavior. >>> >> >> What, based on a comment in lavc? Comments there describe the api but they >> rarely define it. We're free to adjust them if need be and in this case, >> since the codec profile may not be set, the API user is forced to deal with >> the lack of such set. Hence, we can clarify that it may be set by lavf as >> well as lavc as well as not being set at all. And the decoder may use it. >> I maintain that adding a new codec ID for this is unacceptable. >> > > We already have established methods to select codec sub-variants, we > don't need to invent a new one just because you feel like it. > On that note, we also have cases where the same codec has different codec ids based on popular known names. For example wmv3/vc1 - wmv3 is simple/main profile, vc1 is advanced profile, different codec ids, same implementation. Re-defining public API is what is unacceptable, it requires every caller of lavc to suddenly start handling one more field for no real reason. Either use a separate codec ID if there is sufficient reason for that (mostly driven by external factors, if its handled as different codecs everywhere else, not only in marketing but actual (reference) implementations), or use a codec_tag if one is available (the codec id field from a2dp for example) - Hendrik ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH v2 1/1] avformat/hlsenc: closed caption tags in the master playlist
> On 9 Jan 2018, at 16:45, vdi...@akamai.com wrote: > > From: Vishwanath Dixit > > --- > doc/muxers.texi | 37 +++ > libavformat/dashenc.c | 2 +- > libavformat/hlsenc.c | 155 +- > libavformat/hlsplaylist.c | 5 +- > libavformat/hlsplaylist.h | 3 +- > 5 files changed, 197 insertions(+), 5 deletions(-) > > diff --git a/doc/muxers.texi b/doc/muxers.texi > index b060c4f..d9a5cc0 100644 > --- a/doc/muxers.texi > +++ b/doc/muxers.texi > @@ -901,6 +901,43 @@ and they are mapped to the two video only variant > streams with audio group names > > By default, a single hls variant containing all the encoded streams is > created. > > +@item cc_stream_map > +Map string which specifies different closed captions groups and their > +attributes. The closed captions stream groups are separated by space. > +Expected string format is like this > +"ccgroup:,instreamid:,language: > ". > +'ccgroup' and 'instreamid' are mandatory attributes. 'language' is an > optional > +attribute. > +The closed captions groups configured using this option are mapped to > different > +variant streams by providing the same 'ccgroup' name in the > +@code{var_stream_map} string. If @code{var_stream_map} is not set, then the > +first available ccgroup in @code{cc_stream_map} is mapped to the output > variant > +stream. The examples for these two use cases are given below. > + > +@example > +ffmpeg -re -i in.ts -b:v 1000k -b:a 64k -a53cc 1 -f hls \ > + -cc_stream_map "ccgroup:cc,instreamid:CC1,language:en" \ > + -master_pl_name master.m3u8 \ > + http://example.com/live/out.m3u8 > +@end example > +This example adds @code{#EXT-X-MEDIA} tag with @code{TYPE=CLOSED-CAPTIONS} in > +the master playlist with group name 'cc', langauge 'en' (english) and > +INSTREAM-ID 'CC1'. Also, it adds @code{CLOSED-CAPTIONS} attribute with group > +name 'cc' for the output variant stream. > +@example > +ffmpeg -re -i in.ts -b:v:0 1000k -b:v:1 256k -b:a:0 64k -b:a:1 32k \ > + -a53cc:0 1 -a53cc:1 1\ > + -map 0:v -map 0:a -map 0:v -map 0:a -f hls \ > + -cc_stream_map "ccgroup:cc,instreamid:CC1,language:en > ccgroup:cc,instreamid:CC2,language:sp" \ > + -var_stream_map "v:0,a:0,ccgroup:cc v:1,a:1,ccgroup:cc" \ > + -master_pl_name master.m3u8 \ > + http://example.com/live/out_%v.m3u8 > +@end example > +This example adds two @code{#EXT-X-MEDIA} tags with > @code{TYPE=CLOSED-CAPTIONS} in > +the master playlist for the INSTREAM-IDs 'CC1' and 'CC2'. Also, it adds > +@code{CLOSED-CAPTIONS} attribute with group name 'cc' for the two output > variant > +streams. > + > @item master_pl_name > Create HLS master playlist with the given name. > > diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c > index 3345b89..39d0afe 100644 > --- a/libavformat/dashenc.c > +++ b/libavformat/dashenc.c > @@ -820,7 +820,7 @@ static int write_manifest(AVFormatContext *s, int final) > stream_bitrate += max_audio_bitrate; > } > get_hls_playlist_name(playlist_file, sizeof(playlist_file), NULL, > i); > -ff_hls_write_stream_info(st, out, stream_bitrate, playlist_file, > agroup); > +ff_hls_write_stream_info(st, out, stream_bitrate, playlist_file, > agroup, NULL); > } > avio_close(out); > if (use_rename) > diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c > index e36120c..4e4b287 100644 > --- a/libavformat/hlsenc.c > +++ b/libavformat/hlsenc.c > @@ -145,9 +145,16 @@ typedef struct VariantStream { > unsigned int nb_streams; > int m3u8_created; /* status of media play-list creation */ > char *agroup; /* audio group name */ > +char *ccgroup; /* closed caption group name */ > char *baseurl; > } VariantStream; > > +typedef struct ClosedCaptionsStream { > +char *ccgroup; /* closed caption group name */ > +char *instreamid; /* closed captions INSTREAM-ID */ > +char *language; /* closed captions langauge */ > +} ClosedCaptionsStream; > + > typedef struct HLSContext { > const AVClass *class; // Class for private options. > int64_t start_sequence; > @@ -196,11 +203,14 @@ typedef struct HLSContext { > > VariantStream *var_streams; > unsigned int nb_varstreams; > +ClosedCaptionsStream *cc_streams; > +unsigned int nb_ccstreams; > > int master_m3u8_created; /* status of master play-list creation */ > char *master_m3u8_url; /* URL of the master m3u8 file */ > int version; /* HLS version */ > char *var_stream_map; /* user specified variant stream map string */ > +char *cc_stream_map; /* user specified closed caption streams map string > */ > char *master_pl_name; > unsigned int master_publish_rate; > int http_persistent; > @@ -1115,7 +1125,8 @@ static int create_master_playlist(AVFormatContext *s, > AVDictionary *options = NULL; > unsigned int i, j; > int m3u8_name_size, ret, bandwidth; > -char *m3u8_rel_name; > +
Re: [FFmpeg-devel] [PATCH v2 1/1] avformat/hlsenc: closed caption tags in the master playlist
>> > > If only copy command of the document, it’s ok, > If input string by myself, It’s have problem, cannot be used. > > > liuqideMacBook-Pro:xxx liuqi$ ./ffmpeg -re -f lavfi -i color=red -g 25 -b:v > 1000k -b:a 64k -a53cc 1 -f hls -cc_stream_map > "ccgroup:cc,instreamid:CC1,language:en" -master_pl_name master.m3u8 > live/out.m3u8 > ffmpeg version N-89757-g42a5fe340f Copyright (c) 2000-2018 the FFmpeg > developers > built with Apple LLVM version 9.0.0 (clang-900.0.39.2) > configuration: --enable-fontconfig --enable-gpl --enable-libass > --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libspeex > --enable-libx264 --enable-libx265 --enable-libfdk-aac --enable-version3 > --cc='ccache gcc' --enable-nonfree --enable-videotoolbox > libavutil 56. 7.100 / 56. 7.100 > libavcodec 58. 9.100 / 58. 9.100 > libavformat58. 3.100 / 58. 3.100 > libavdevice58. 0.100 / 58. 0.100 > libavfilter 7. 11.101 / 7. 11.101 > libswscale 5. 0.101 / 5. 0.101 > libswresample 3. 0.101 / 3. 0.101 > libpostproc55. 0.100 / 55. 0.100 > Input #0, lavfi, from 'color=red': > Duration: N/A, start: 0.00, bitrate: N/A >Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p, 320x240 [SAR > 1:1 DAR 4:3], 25 tbr, 25 tbn, 25 tbc > Stream mapping: > Stream #0:0 -> #0:0 (rawvideo (native) -> h264 (libx264)) > Press [q] to stop, [?] for help > [libx264 @ 0x7fadae801600] using SAR=1/1 > [libx264 @ 0x7fadae801600] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 > AVX > [libx264 @ 0x7fadae801600] profile High, level 2.0 > [libx264 @ 0x7fadae801600] 264 - core 148 r2694 3b70645 - H.264/MPEG-4 AVC > codec - Copyleft 2003-2016 - http://www.videolan.org/x264.html - options: > cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 > psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 > deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=6 lookahead_threads=1 > sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 > constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 > weightb=1 open_gop=0 weightp=2 keyint=25 keyint_min=2 scenecut=40 > intra_refresh=0 rc_lookahead=25 rc=abr mbtree=1 bitrate=1000 ratetol=1.0 > qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00 > [hls @ 0x7fadae81ec00] Opening 'live/out0.ts' for writing > Output #0, hls, to 'live/out.m3u8': > Metadata: >encoder : Lavf58.3.100 >Stream #0:0: Video: h264 (libx264), yuv420p, 320x240 [SAR 1:1 DAR 4:3], > q=-1--1, 1000 kb/s, 25 fps, 90k tbn, 25 tbc >Metadata: > encoder : Lavc58.9.100 libx264 >Side data: > cpb: bitrate max/min/avg: 0/0/100 buffer size: 0 vbv_delay: -1 > [hls @ 0x7fadae81ec00] Opening 'live/out1.ts' for writingte=N/A speed=0.514x > [hls @ 0x7fadae81ec00] Opening 'live/out.m3u8.tmp' for writing > [hls @ 0x7fadae81ec00] Opening 'live/master.m3u8' for writing > [hls @ 0x7fadae81ec00] Opening 'live/out2.ts' for writingte=N/A speed=0.71x > [hls @ 0x7fadae81ec00] Opening 'live/out.m3u8.tmp' for writing > [hls @ 0x7fadae81ec00] Opening 'live/out3.ts' for writingte=N/A speed=0.794x > [hls @ 0x7fadae81ec00] Opening 'live/out.m3u8.tmp' for writing > [hls @ 0x7fadae81ec00] Opening 'live/out4.ts' for writingte=N/A speed=0.809x > [hls @ 0x7fadae81ec00] Opening 'live/out.m3u8.tmp' for writing > [hls @ 0x7fadae81ec00] Opening 'live/out.m3u8.tmp' for writing > frame= 202 fps= 25 q=-1.0 Lsize=N/A time=00:00:08.00 bitrate=N/A speed=0.99x > video:5kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing > overhead: unknown > [libx264 @ 0x7fadae801600] frame I:9 Avg QP: 0.44 size:72 > [libx264 @ 0x7fadae801600] frame P:49Avg QP: 0.14 size:22 > [libx264 @ 0x7fadae801600] frame B:144 Avg QP: 0.36 size:16 > [libx264 @ 0x7fadae801600] consecutive B-frames: 5.0% 0.0% 0.0% 95.0% > [libx264 @ 0x7fadae801600] mb I I16..4: 100.0% 0.0% 0.0% > [libx264 @ 0x7fadae801600] mb P I16..4: 0.0% 0.0% 0.0% P16..4: 0.0% > 0.0% 0.0% 0.0% 0.0%skip:100.0% > [libx264 @ 0x7fadae801600] mb B I16..4: 0.0% 0.0% 0.0% B16..8: 0.0% > 0.0% 0.0% direct: 0.0% skip:100.0% > [libx264 @ 0x7fadae801600] final ratefactor: -27.54 > [libx264 @ 0x7fadae801600] 8x8 transform intra:0.0% > [libx264 @ 0x7fadae801600] coded y,uvDC,uvAC intra: 0.0% 0.3% 0.0% inter: > 0.0% 0.0% 0.0% > [libx264 @ 0x7fadae801600] i16 v,h,dc,p: 93% 0% 7% 0% > [libx264 @ 0x7fadae801600] i8c dc,h,v,p: 100% 0% 0% 0% > [libx264 @ 0x7fadae801600] Weighted P-Frames: Y:0.0% UV:0.0% > [libx264 @ 0x7fadae801600] kb/s:4.05 > > > > liuqideMacBook-Pro:xxx liuqi$ ./ffmpeg -re -f lavfi -i color=red -g 25 -b:v > 1000k -b:a 64k -a53cc 1 -f hls -cc_stream_map > "closecgroup:cc,instreamid:CC1,language:en" -master_pl_name master.m3u8 > live/out.m3u8 > ffmpeg version N-89757-g42a5fe340f Copyright (c) 2000-2018 the FFmpeg > developers > built with Apple LLVM vers
Re: [FFmpeg-devel] [PATCH v2 1/1] avformat/hlsenc: closed caption tags in the master playlist
On 1/9/18 2:41 PM, 刘歧 wrote: >>> >> >> If only copy command of the document, it’s ok, >> If input string by myself, It’s have problem, cannot be used. >> >> >> liuqideMacBook-Pro:xxx liuqi$ ./ffmpeg -re -f lavfi -i color=red -g 25 >> -b:v 1000k -b:a 64k -a53cc 1 -f hls -cc_stream_map >> "ccgroup:cc,instreamid:CC1,language:en" -master_pl_name master.m3u8 >> live/out.m3u8 >> ffmpeg version N-89757-g42a5fe340f Copyright (c) 2000-2018 the FFmpeg >> developers >> built with Apple LLVM version 9.0.0 (clang-900.0.39.2) >> configuration: --enable-fontconfig --enable-gpl --enable-libass >> --enable-libbluray --enable-libfreetype --enable-libmp3lame >> --enable-libspeex --enable-libx264 --enable-libx265 --enable-libfdk-aac >> --enable-version3 --cc='ccache gcc' --enable-nonfree --enable-videotoolbox >> libavutil 56. 7.100 / 56. 7.100 >> libavcodec 58. 9.100 / 58. 9.100 >> libavformat58. 3.100 / 58. 3.100 >> libavdevice58. 0.100 / 58. 0.100 >> libavfilter 7. 11.101 / 7. 11.101 >> libswscale 5. 0.101 / 5. 0.101 >> libswresample 3. 0.101 / 3. 0.101 >> libpostproc55. 0.100 / 55. 0.100 >> Input #0, lavfi, from 'color=red': >> Duration: N/A, start: 0.00, bitrate: N/A >>Stream #0:0: Video: rawvideo (I420 / 0x30323449), yuv420p, 320x240 [SAR >> 1:1 DAR 4:3], 25 tbr, 25 tbn, 25 tbc >> Stream mapping: >> Stream #0:0 -> #0:0 (rawvideo (native) -> h264 (libx264)) >> Press [q] to stop, [?] for help >> [libx264 @ 0x7fadae801600] using SAR=1/1 >> [libx264 @ 0x7fadae801600] using cpu capabilities: MMX2 SSE2Fast SSSE3 >> SSE4.2 AVX >> [libx264 @ 0x7fadae801600] profile High, level 2.0 >> [libx264 @ 0x7fadae801600] 264 - core 148 r2694 3b70645 - H.264/MPEG-4 AVC >> codec - Copyleft 2003-2016 - http://www.videolan.org/x264.html - options: >> cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 >> psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 >> cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=6 >> lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 >> bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 >> direct=1 weightb=1 open_gop=0 weightp=2 keyint=25 keyint_min=2 scenecut=40 >> intra_refresh=0 rc_lookahead=25 rc=abr mbtree=1 bitrate=1000 ratetol=1.0 >> qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00 >> [hls @ 0x7fadae81ec00] Opening 'live/out0.ts' for writing >> Output #0, hls, to 'live/out.m3u8': >> Metadata: >>encoder : Lavf58.3.100 >>Stream #0:0: Video: h264 (libx264), yuv420p, 320x240 [SAR 1:1 DAR 4:3], >> q=-1--1, 1000 kb/s, 25 fps, 90k tbn, 25 tbc >>Metadata: >> encoder : Lavc58.9.100 libx264 >>Side data: >> cpb: bitrate max/min/avg: 0/0/100 buffer size: 0 vbv_delay: -1 >> [hls @ 0x7fadae81ec00] Opening 'live/out1.ts' for writingte=N/A speed=0.514x >> [hls @ 0x7fadae81ec00] Opening 'live/out.m3u8.tmp' for writing >> [hls @ 0x7fadae81ec00] Opening 'live/master.m3u8' for writing >> [hls @ 0x7fadae81ec00] Opening 'live/out2.ts' for writingte=N/A speed=0.71x >> [hls @ 0x7fadae81ec00] Opening 'live/out.m3u8.tmp' for writing >> [hls @ 0x7fadae81ec00] Opening 'live/out3.ts' for writingte=N/A speed=0.794x >> [hls @ 0x7fadae81ec00] Opening 'live/out.m3u8.tmp' for writing >> [hls @ 0x7fadae81ec00] Opening 'live/out4.ts' for writingte=N/A speed=0.809x >> [hls @ 0x7fadae81ec00] Opening 'live/out.m3u8.tmp' for writing >> [hls @ 0x7fadae81ec00] Opening 'live/out.m3u8.tmp' for writing >> frame= 202 fps= 25 q=-1.0 Lsize=N/A time=00:00:08.00 bitrate=N/A speed=0.99x >> video:5kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing >> overhead: unknown >> [libx264 @ 0x7fadae801600] frame I:9 Avg QP: 0.44 size:72 >> [libx264 @ 0x7fadae801600] frame P:49Avg QP: 0.14 size:22 >> [libx264 @ 0x7fadae801600] frame B:144 Avg QP: 0.36 size:16 >> [libx264 @ 0x7fadae801600] consecutive B-frames: 5.0% 0.0% 0.0% 95.0% >> [libx264 @ 0x7fadae801600] mb I I16..4: 100.0% 0.0% 0.0% >> [libx264 @ 0x7fadae801600] mb P I16..4: 0.0% 0.0% 0.0% P16..4: 0.0% >> 0.0% 0.0% 0.0% 0.0%skip:100.0% >> [libx264 @ 0x7fadae801600] mb B I16..4: 0.0% 0.0% 0.0% B16..8: 0.0% >> 0.0% 0.0% direct: 0.0% skip:100.0% >> [libx264 @ 0x7fadae801600] final ratefactor: -27.54 >> [libx264 @ 0x7fadae801600] 8x8 transform intra:0.0% >> [libx264 @ 0x7fadae801600] coded y,uvDC,uvAC intra: 0.0% 0.3% 0.0% inter: >> 0.0% 0.0% 0.0% >> [libx264 @ 0x7fadae801600] i16 v,h,dc,p: 93% 0% 7% 0% >> [libx264 @ 0x7fadae801600] i8c dc,h,v,p: 100% 0% 0% 0% >> [libx264 @ 0x7fadae801600] Weighted P-Frames: Y:0.0% UV:0.0% >> [libx264 @ 0x7fadae801600] kb/s:4.05 >> >> >> >> liuqideMacBook-Pro:xxx liuqi$ ./ffmpeg -re -f lavfi -i color=red -g 25 >> -b:v 1000k -b:a 64k -a53cc 1 -f hls -cc_stream_map >> "closecgroup:cc,instreamid:CC1,language:en" -master_pl_name master.m3u8 >> live/out.m3u
Re: [FFmpeg-devel] [PATCH v2 1/1] avformat/hlsenc: closed caption tags in the master playlist
>>> >> >> >> I cannot sure use -cc_stream_map_ccgroup option is ok, because the ccgroup >> string is not standard, maybe it can be defined bu user. >> Maybe two ways: >> 1. use -cc_stream_map_ccgroup ? this way is defined the name by ffmpeg, >> cannot modify. >> 2. parse the closed captions group string by KeyValue way? maybe this is >> better. > > Actually, these requirements have been already handled. The parsing is > happening based on key value pairs. The keys are ‘ccgroup’, ‘instreamid’, > ‘language’. The values for these keys can be set after ‘:’ as given the > examples in the patch. > I am assuming you are trying to set ccgroup name as closecgroup. In that > case, please modify the command as below. Because, the string ‘ccgroup’ is a > key value, whatever string that comes after ‘ccgroup:’ is the cc group name. > ./ffmpeg -re -f lavfi -i color=red -g 25 -b:v 1000k -b:a 64k -a53cc 1 -f > hls -cc_stream_map "ccgroup:closecgroup,instreamid:CC1,language:en" > -master_pl_name master.m3u8 live/out.m3u8 > > To clarify further, consider user wants to set cc group name as ‘mycaptions’, > instream id as ‘SERVICE60’ language as Spanish, in that case, the map string > would be > -cc_stream_map "ccgroup:mycaptions,instreamid:SERVICE60,language:sp” I understand and i got the point, just one question, do you want force the user use ffmpeg must input a string “ccgroup” ? if yes, maybe don’t let the user input it use string, maybe use -cc_stream_map_ccgroup is better, What do you think about it? Thanks Steven ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH v2 1/1] avformat/hlsenc: closed caption tags in the master playlist
On 1/9/18 3:05 PM, 刘歧 wrote: >>> >>> >>> I cannot sure use -cc_stream_map_ccgroup option is ok, because the ccgroup >>> string is not standard, maybe it can be defined bu user. >>> Maybe two ways: >>> 1. use -cc_stream_map_ccgroup ? this way is defined the name by ffmpeg, >>> cannot modify. >>> 2. parse the closed captions group string by KeyValue way? maybe this is >>> better. >> >> Actually, these requirements have been already handled. The parsing is >> happening based on key value pairs. The keys are ‘ccgroup’, ‘instreamid’, >> ‘language’. The values for these keys can be set after ‘:’ as given the >> examples in the patch. >> I am assuming you are trying to set ccgroup name as closecgroup. In that >> case, please modify the command as below. Because, the string ‘ccgroup’ is a >> key value, whatever string that comes after ‘ccgroup:’ is the cc group name. >> >> ./ffmpeg -re -f lavfi -i color=red -g 25 -b:v 1000k -b:a 64k -a53cc 1 -f >> hls -cc_stream_map "ccgroup:closecgroup,instreamid:CC1,language:en" >> -master_pl_name master.m3u8 live/out.m3u8 >> >> To clarify further, consider user wants to set cc group name as >> ‘mycaptions’, instream id as ‘SERVICE60’ language as Spanish, in that case, >> the map string would be >> -cc_stream_map "ccgroup:mycaptions,instreamid:SERVICE60,language:sp” > I understand and i got the point, > just one question, do you want force the user use ffmpeg must input a string > “ccgroup” ? if yes, maybe don’t let the user input it use string, maybe use > -cc_stream_map_ccgroup is better, What do you think about it? Are you suggesting to change the string from ‘–cc_stream_map’ to ‘-cc_stream_map_ccgroup’ and remove the ‘ccgroup’ key from the value string? Could you please clarify? Apart from this, I would like to highlight some advanced use cases where current implementation will be more meaningful. It is possible that that there could be multiple instream ids under the same closed caption group or there can be different closed captions groups. Example: -cc_stream_map "ccgroup:group1,instreamid:CC1,language:en ccgroup:group1,instreamid:CC2,language:sp” -cc_stream_map "ccgroup:eng_group,instreamid:CC1,language:en ccgroup:span_group,instreamid:CC1,language:sp” In these cases, the same ccgroup is mentioned in the –var_stream_map string as well. -var_stream_map "v:0,a:0,ccgroup:group1 v:1,a:1,ccgroup:group1" or -var_stream_map "v:0,a:0,ccgroup:eng_group v:1,a:1,ccgroup:span_group" Here, ‘ccgroup’ is a common key between –cc_stream_map and –var_stream_map. So, it is better to keep this key so that it will more readable and easily configurable for the user. > > > Thanks > > Steven > > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 4/5] aptx: implement the aptX HD bluetooth codec
On 9 January 2018 at 09:00, Hendrik Leppkes wrote: > On Tue, Jan 9, 2018 at 9:33 AM, Hendrik Leppkes > wrote: > > On Tue, Jan 9, 2018 at 5:07 AM, Rostislav Pehlivanov > > wrote: > >> > >>> Anyway, all this discussion is moot as Hendrik pointed out that profile > >>> can't be set outside of lavc to determine a decoder behavior. > >>> > >> > >> What, based on a comment in lavc? Comments there describe the api but > they > >> rarely define it. We're free to adjust them if need be and in this case, > >> since the codec profile may not be set, the API user is forced to deal > with > >> the lack of such set. Hence, we can clarify that it may be set by lavf > as > >> well as lavc as well as not being set at all. And the decoder may use > it. > >> I maintain that adding a new codec ID for this is unacceptable. > >> > > > > We already have established methods to select codec sub-variants, we > > don't need to invent a new one just because you feel like it. > > > > On that note, we also have cases where the same codec has different > codec ids based on popular known names. > For example wmv3/vc1 - wmv3 is simple/main profile, vc1 is advanced > profile, different codec ids, same implementation. > > Re-defining public API is what is unacceptable, it requires every > caller of lavc to suddenly start handling one more field for no real > reason. > Then its a good thing I suggested something that doesn't involve having every caller of lavc to handle another field. > Either use a separate codec ID if there is sufficient reason for that > (mostly driven by external factors, if its handled as different codecs > everywhere else, not only in marketing but actual (reference) > implementations), or use a codec_tag if one is available (the codec id > field from a2dp for example) > > - Hendrik > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > I'd be fine with using codec tags, but not with codec IDs. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 4/5] aptx: implement the aptX HD bluetooth codec
On 9 January 2018 at 14:07, Rostislav Pehlivanov wrote: > > > On 9 January 2018 at 09:00, Hendrik Leppkes wrote: > >> On Tue, Jan 9, 2018 at 9:33 AM, Hendrik Leppkes >> wrote: >> > On Tue, Jan 9, 2018 at 5:07 AM, Rostislav Pehlivanov >> > wrote: >> >> >> >>> Anyway, all this discussion is moot as Hendrik pointed out that >> profile >> >>> can't be set outside of lavc to determine a decoder behavior. >> >>> >> >> >> >> What, based on a comment in lavc? Comments there describe the api but >> they >> >> rarely define it. We're free to adjust them if need be and in this >> case, >> >> since the codec profile may not be set, the API user is forced to deal >> with >> >> the lack of such set. Hence, we can clarify that it may be set by lavf >> as >> >> well as lavc as well as not being set at all. And the decoder may use >> it. >> >> I maintain that adding a new codec ID for this is unacceptable. >> >> >> > >> > We already have established methods to select codec sub-variants, we >> > don't need to invent a new one just because you feel like it. >> > >> >> On that note, we also have cases where the same codec has different >> codec ids based on popular known names. >> For example wmv3/vc1 - wmv3 is simple/main profile, vc1 is advanced >> profile, different codec ids, same implementation. >> >> Re-defining public API is what is unacceptable, it requires every >> caller of lavc to suddenly start handling one more field for no real >> reason. >> > > Then its a good thing I suggested something that doesn't involve having > every caller of lavc to handle another field. > > > >> Either use a separate codec ID if there is sufficient reason for that >> (mostly driven by external factors, if its handled as different codecs >> everywhere else, not only in marketing but actual (reference) >> implementations), or use a codec_tag if one is available (the codec id >> field from a2dp for example) >> >> - Hendrik >> ___ >> ffmpeg-devel mailing list >> ffmpeg-devel@ffmpeg.org >> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel >> > > I'd be fine with using codec tags, but not with codec IDs. > Though for encoding using profiles would be best. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 4/5] aptx: implement the aptX HD bluetooth codec
On Tue, Jan 9, 2018 at 3:21 PM, Rostislav Pehlivanov wrote: > On 9 January 2018 at 14:07, Rostislav Pehlivanov > wrote: > >> >> >> On 9 January 2018 at 09:00, Hendrik Leppkes wrote: >> >>> On Tue, Jan 9, 2018 at 9:33 AM, Hendrik Leppkes >>> wrote: >>> > On Tue, Jan 9, 2018 at 5:07 AM, Rostislav Pehlivanov >>> > wrote: >>> >> >>> >>> Anyway, all this discussion is moot as Hendrik pointed out that >>> profile >>> >>> can't be set outside of lavc to determine a decoder behavior. >>> >>> >>> >> >>> >> What, based on a comment in lavc? Comments there describe the api but >>> they >>> >> rarely define it. We're free to adjust them if need be and in this >>> case, >>> >> since the codec profile may not be set, the API user is forced to deal >>> with >>> >> the lack of such set. Hence, we can clarify that it may be set by lavf >>> as >>> >> well as lavc as well as not being set at all. And the decoder may use >>> it. >>> >> I maintain that adding a new codec ID for this is unacceptable. >>> >> >>> > >>> > We already have established methods to select codec sub-variants, we >>> > don't need to invent a new one just because you feel like it. >>> > >>> >>> On that note, we also have cases where the same codec has different >>> codec ids based on popular known names. >>> For example wmv3/vc1 - wmv3 is simple/main profile, vc1 is advanced >>> profile, different codec ids, same implementation. >>> >>> Re-defining public API is what is unacceptable, it requires every >>> caller of lavc to suddenly start handling one more field for no real >>> reason. >>> >> >> Then its a good thing I suggested something that doesn't involve having >> every caller of lavc to handle another field. >> >> >> >>> Either use a separate codec ID if there is sufficient reason for that >>> (mostly driven by external factors, if its handled as different codecs >>> everywhere else, not only in marketing but actual (reference) >>> implementations), or use a codec_tag if one is available (the codec id >>> field from a2dp for example) >>> >>> - Hendrik >> >> I'd be fine with using codec tags, but not with codec IDs. >> > > Though for encoding using profiles would be best. For encoding, profiles is perfectly normal and expected, and used by many other codecs as well. Just for decoding that field is not defined to be required to be set externally to even make decoding of a certain stream possible. - Hendrik ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/3] avcodec: v4l2_m2m: fix races around freeing data on close
From: Mark Thompson Refcount all of the context information. This also fixes a potential segmentation fault when accessing freed memory (buffer returned after the codec has been closed). Tested-by: Jorge Ramirez-Ortiz --- libavcodec/v4l2_buffers.c | 32 ++-- libavcodec/v4l2_buffers.h | 6 +++ libavcodec/v4l2_m2m.c | 93 +-- libavcodec/v4l2_m2m.h | 35 ++ libavcodec/v4l2_m2m_dec.c | 22 +++ libavcodec/v4l2_m2m_enc.c | 22 +++ 6 files changed, 140 insertions(+), 70 deletions(-) diff --git a/libavcodec/v4l2_buffers.c b/libavcodec/v4l2_buffers.c index ba70c5d..4e68f90 100644 --- a/libavcodec/v4l2_buffers.c +++ b/libavcodec/v4l2_buffers.c @@ -207,20 +207,17 @@ static void v4l2_free_buffer(void *opaque, uint8_t *unused) V4L2Buffer* avbuf = opaque; V4L2m2mContext *s = buf_to_m2mctx(avbuf); -atomic_fetch_sub_explicit(&s->refcount, 1, memory_order_acq_rel); -if (s->reinit) { -if (!atomic_load(&s->refcount)) -sem_post(&s->refsync); -return; -} +if (atomic_fetch_sub(&avbuf->context_refcount, 1) == 1) { +atomic_fetch_sub_explicit(&s->refcount, 1, memory_order_acq_rel); -if (avbuf->context->streamon) { -ff_v4l2_buffer_enqueue(avbuf); -return; -} +if (s->reinit) { +if (!atomic_load(&s->refcount)) +sem_post(&s->refsync); +} else if (avbuf->context->streamon) +ff_v4l2_buffer_enqueue(avbuf); -if (!atomic_load(&s->refcount)) -ff_v4l2_m2m_codec_end(s->avctx); +av_buffer_unref(&avbuf->context_ref); +} } static int v4l2_buf_to_bufref(V4L2Buffer *in, int plane, AVBufferRef **buf) @@ -236,6 +233,17 @@ static int v4l2_buf_to_bufref(V4L2Buffer *in, int plane, AVBufferRef **buf) if (!*buf) return AVERROR(ENOMEM); +if (in->context_ref) +atomic_fetch_add(&in->context_refcount, 1); +else { +in->context_ref = av_buffer_ref(s->self_ref); +if (!in->context_ref) { +av_buffer_unref(buf); +return AVERROR(ENOMEM); +} +in->context_refcount = 1; +} + in->status = V4L2BUF_RET_USER; atomic_fetch_add_explicit(&s->refcount, 1, memory_order_relaxed); diff --git a/libavcodec/v4l2_buffers.h b/libavcodec/v4l2_buffers.h index e28a4a6..dc5cc9e 100644 --- a/libavcodec/v4l2_buffers.h +++ b/libavcodec/v4l2_buffers.h @@ -24,6 +24,7 @@ #ifndef AVCODEC_V4L2_BUFFERS_H #define AVCODEC_V4L2_BUFFERS_H +#include #include #include "avcodec.h" @@ -41,6 +42,11 @@ typedef struct V4L2Buffer { /* each buffer needs to have a reference to its context */ struct V4L2Context *context; +/* This object is refcounted per-plane, so we need to keep track + * of how many context-refs we are holding. */ +AVBufferRef *context_ref; +atomic_uint context_refcount; + /* keep track of the mmap address and mmap length */ struct V4L2Plane_info { int bytesperline; diff --git a/libavcodec/v4l2_m2m.c b/libavcodec/v4l2_m2m.c index 1d7a852..fd989ce 100644 --- a/libavcodec/v4l2_m2m.c +++ b/libavcodec/v4l2_m2m.c @@ -222,8 +222,6 @@ int ff_v4l2_m2m_codec_reinit(V4L2m2mContext* s) } /* 5. complete reinit */ -sem_destroy(&s->refsync); -sem_init(&s->refsync, 0, 0); s->draining = 0; s->reinit = 0; @@ -241,24 +239,26 @@ int ff_v4l2_m2m_codec_full_reinit(V4L2m2mContext *s) if (atomic_load(&s->refcount)) while(sem_wait(&s->refsync) == -1 && errno == EINTR); -/* close the driver */ -ff_v4l2_m2m_codec_end(s->avctx); +ret = ff_v4l2_context_set_status(&s->output, VIDIOC_STREAMOFF); +if (ret) { +av_log(s->avctx, AV_LOG_ERROR, "output VIDIOC_STREAMOFF\n"); +goto error; +} + +ret = ff_v4l2_context_set_status(&s->capture, VIDIOC_STREAMOFF); +if (ret) { +av_log(s->avctx, AV_LOG_ERROR, "capture VIDIOC_STREAMOFF\n"); +goto error; +} + +/* release and unmmap the buffers */ +ff_v4l2_context_release(&s->output); +ff_v4l2_context_release(&s->capture); /* start again now that we know the stream dimensions */ s->draining = 0; s->reinit = 0; -s->fd = open(s->devname, O_RDWR | O_NONBLOCK, 0); -if (s->fd < 0) -return AVERROR(errno); - -ret = v4l2_prepare_contexts(s); -if (ret < 0) -goto error; - -/* if a full re-init was requested - probe didn't run - we need to populate - * the format for each context - */ ret = ff_v4l2_context_get_format(&s->output); if (ret) { av_log(log_ctx, AV_LOG_DEBUG, "v4l2 output format not supported\n"); @@ -301,19 +301,25 @@ int ff_v4l2_m2m_codec_full_reinit(V4L2m2mContext *s) return 0; error: -if (close(s->fd) < 0) { -ret = AVERROR(errno); -av_log(log_ctx, AV_LOG_ERROR, "error closing %s (%s)\n", -s->devname, av
[FFmpeg-devel] [PATCH 2/3] avcodec: v4l2_m2m: remove unnecessary timeout.
From: Jorge Ramirez-Ortiz Qualcomm's db410c/db820 Venus driver currently present in mainline kernel has a bug which mishandles the CMD_STOP requests causing the decoder to block while draining [1]. This patch removes the workaround that was used to prevent that situation. Encoding/Decoding tested on db820c. [1] on CMD_STOP, the driver is flushing all buffers and never raising IPIPE which ends up in blocking on poll. --- libavcodec/v4l2_buffers.c | 10 -- libavcodec/v4l2_context.c | 48 +++ libavcodec/v4l2_m2m_dec.c | 14 +++--- libavcodec/v4l2_m2m_enc.c | 14 +++--- 4 files changed, 54 insertions(+), 32 deletions(-) diff --git a/libavcodec/v4l2_buffers.c b/libavcodec/v4l2_buffers.c index 4e68f90..8e4d4d1 100644 --- a/libavcodec/v4l2_buffers.c +++ b/libavcodec/v4l2_buffers.c @@ -213,8 +213,14 @@ static void v4l2_free_buffer(void *opaque, uint8_t *unused) if (s->reinit) { if (!atomic_load(&s->refcount)) sem_post(&s->refsync); -} else if (avbuf->context->streamon) -ff_v4l2_buffer_enqueue(avbuf); +} else { +if (s->draining) { +/* no need to queue more buffers to the driver */ +avbuf->status = V4L2BUF_AVAILABLE; +} +else if (avbuf->context->streamon) +ff_v4l2_buffer_enqueue(avbuf); +} av_buffer_unref(&avbuf->context_ref); } diff --git a/libavcodec/v4l2_context.c b/libavcodec/v4l2_context.c index 4c16992..fb482cf 100644 --- a/libavcodec/v4l2_context.c +++ b/libavcodec/v4l2_context.c @@ -217,6 +217,7 @@ static int v4l2_stop_decode(V4L2Context *ctx) { struct v4l2_decoder_cmd cmd = { .cmd = V4L2_DEC_CMD_STOP, +.flags = 0, }; int ret; @@ -234,6 +235,7 @@ static int v4l2_stop_encode(V4L2Context *ctx) { struct v4l2_encoder_cmd cmd = { .cmd = V4L2_ENC_CMD_STOP, +.flags = 0, }; int ret; @@ -260,6 +262,11 @@ static V4L2Buffer* v4l2_dequeue_v4l2buf(V4L2Context *ctx, int timeout) if (V4L2_TYPE_IS_OUTPUT(ctx->type)) pfd.events = POLLOUT | POLLWRNORM; +else { +/* no need to listen to requests for more input while draining */ +if (ctx_to_m2mctx(ctx)->draining) +pfd.events = POLLIN | POLLRDNORM | POLLPRI; +} for (;;) { ret = poll(&pfd, 1, timeout); @@ -267,11 +274,6 @@ static V4L2Buffer* v4l2_dequeue_v4l2buf(V4L2Context *ctx, int timeout) break; if (errno == EINTR) continue; - -/* timeout is being used to indicate last valid bufer when draining */ -if (ctx_to_m2mctx(ctx)->draining) -ctx->done = 1; - return NULL; } @@ -286,7 +288,7 @@ static V4L2Buffer* v4l2_dequeue_v4l2buf(V4L2Context *ctx, int timeout) ret = v4l2_handle_event(ctx); if (ret < 0) { /* if re-init failed, abort */ -ctx->done = EINVAL; +ctx->done = 1; return NULL; } if (ret) { @@ -325,23 +327,25 @@ dequeue: ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_DQBUF, &buf); if (ret) { if (errno != EAGAIN) { -ctx->done = errno; +ctx->done = 1; if (errno != EPIPE) av_log(logger(ctx), AV_LOG_DEBUG, "%s VIDIOC_DQBUF, errno (%s)\n", ctx->name, av_err2str(AVERROR(errno))); } -} else { -avbuf = &ctx->buffers[buf.index]; -avbuf->status = V4L2BUF_AVAILABLE; -avbuf->buf = buf; -if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) { -memcpy(avbuf->planes, planes, sizeof(planes)); -avbuf->buf.m.planes = avbuf->planes; -} +return NULL; +} + +avbuf = &ctx->buffers[buf.index]; +avbuf->status = V4L2BUF_AVAILABLE; +avbuf->buf = buf; +if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) { +memcpy(avbuf->planes, planes, sizeof(planes)); +avbuf->buf.m.planes = avbuf->planes; } +return avbuf; } -return avbuf; +return NULL; } static V4L2Buffer* v4l2_getfree_v4l2buf(V4L2Context *ctx) @@ -552,14 +556,12 @@ int ff_v4l2_context_dequeue_frame(V4L2Context* ctx, AVFrame* frame) { V4L2Buffer* avbuf = NULL; -/* if we are draining, we are no longer inputing data, therefore enable a - * timeout so we can dequeue and flag the last valid buffer. - * +/* * blocks until: * 1. decoded frame available * 2. an input buffer is ready to be dequeued */ -avbuf = v4l2_dequeue_v4l2buf(ctx, ctx_to_m2mctx(ctx)->draining ? 200 : -1); +avbuf = v4l2_dequeue_v4l2buf(ctx, -1); if (!avbuf) { if (ctx->done) return AVERROR_EOF; @@ -574,14 +576,12 @@ int ff_v4l2_context_dequeue
[FFmpeg-devel] [PATCH 3/3] avcodec: v4l2_m2m: context: fix raising warning on POLLERR
From: Jorge Ramirez-Ortiz During the initialization stage, the codec attempts to get free buffers from the driver before any have been queued (this is to keep the code simple and generic) When the kernel driver detects this situation, it returns POLLERR in revents and ffmpeg therefore raises a warning. This commit disables the warning since no buffers were queued to the driver yet. Signed-off-by: Jorge Ramirez-Ortiz --- libavcodec/v4l2_context.c | 16 ++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/libavcodec/v4l2_context.c b/libavcodec/v4l2_context.c index fb482cf..5bacaaf 100644 --- a/libavcodec/v4l2_context.c +++ b/libavcodec/v4l2_context.c @@ -258,7 +258,7 @@ static V4L2Buffer* v4l2_dequeue_v4l2buf(V4L2Context *ctx, int timeout) .events = POLLIN | POLLRDNORM | POLLPRI | POLLOUT | POLLWRNORM, /* default blocking capture */ .fd = ctx_to_m2mctx(ctx)->fd, }; -int ret; +int i, ret; if (V4L2_TYPE_IS_OUTPUT(ctx->type)) pfd.events = POLLOUT | POLLWRNORM; @@ -279,7 +279,19 @@ static V4L2Buffer* v4l2_dequeue_v4l2buf(V4L2Context *ctx, int timeout) /* 0. handle errors */ if (pfd.revents & POLLERR) { -av_log(logger(ctx), AV_LOG_WARNING, "%s POLLERR\n", ctx->name); + /* if we are trying to get free buffers but none have been queued yet + no need to raise a warning */ + if (timeout == 0 ) { + for (i = 0; i < ctx->num_buffers; i++) { + if (ctx->buffers[i].status != V4L2BUF_AVAILABLE) { + av_log(logger(ctx), AV_LOG_WARNING, "%s POLLERR\n", ctx->name); + return NULL; + } + } + } + else + av_log(logger(ctx), AV_LOG_WARNING, "%s POLLERR\n", ctx->name); + return NULL; } -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] avformat/avio: fix off-by-one in retry_transfer_wrapper
This reportedly fixes hangs with segmented streams. Affects playback via Schannel on Windows in particular. Can be reproduced with any YouTube live stream. --- libavformat/avio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/avio.c b/libavformat/avio.c index 63e82872f7..cd1e325a6b 100644 --- a/libavformat/avio.c +++ b/libavformat/avio.c @@ -393,7 +393,7 @@ static inline int retry_transfer_wrapper(URLContext *h, uint8_t *buf, } } else if (ret == AVERROR_EOF) return (len > 0) ? len : AVERROR_EOF; -else if (ret < 0) +else if (ret <= 0) return ret; if (ret) { fast_retries = FFMAX(fast_retries, 2); -- 2.15.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 1/3] avformat/mov: Increase support for common encryption.
On Mon, Jan 8, 2018 at 5:19 PM, Carl Eugen Hoyos wrote: > 2018-01-08 23:16 GMT+01:00 Jacob Trimble : >>> You can't remove API just like that without a deprecation period. >>> Add a new av_aes_ctr_set_full_iv() function, and either leave >>> av_aes_ctr_set_iv() alone or deprecate it if it effectively becomes >>> superfluous after adding the new function. >>> >>> Also, this patch needs to be split in three. One for the aes_crt >>> changes, one for the encryption_info changes, and one for mov changes, >>> with a minor libavutil version bump for the former two, and the >>> corresponding APIChanges entry. >>> Alternatively, you could also squash the new encryption_info API from >>> this patch into the one that actually introduces the entire feature. >> >> Whoops, I thought that was internal-only. Done and split into its own >> change. >> >> On Sat, Jan 6, 2018 at 7:30 AM, Carl Eugen Hoyos wrote: >>> 2018-01-05 20:49 GMT+01:00 Jacob Trimble >>> : >>> +if (!frag_stream_info->encryption_index) { +frag_stream_info->encryption_index = av_mallocz(sizeof(MOVEncryptionIndex)); >>> >>> sizeof(variable), please. > > Do you disagree? > I have no strong opinion, but I thought it makes the code more robust... I did it most other places, but forgot it here. Done. > >>> [...] >>> +sample_count = avio_rb32(pb); + +encryption_index->encrypted_samples = av_mallocz_array(sizeof(AVEncryptionInfo*), sample_count); >>> >>> This should be avoided if possible, see below. >>> +if (!encryption_index->encrypted_samples) { return AVERROR(ENOMEM); } +encryption_index->nb_encrypted_samples = sample_count; -return av_aes_ctr_init(sc->cenc.aes_ctr, c->decryption_key); +for (i = 0; i < sample_count; i++) { >>> >>> Please check here for eof... >>> +ret = mov_read_sample_encryption_info(c, pb, sc, &encryption_index->encrypted_samples[i], use_subsamples); >>> >>> ... and insert a realloc here to avoid the large allocation above, see >>> 1112ba01. >> >> Done. > >> +if (use_subsamples) { >> +subsample_count = avio_rb16(pb); >> +for (i = 0; i < subsample_count && !pb->eof_reached; i++) { >> +unsigned int min_subsamples = FFMIN(FFMAX(i, 1024 * 1024), >> subsample_count); >> +subsamples = av_fast_realloc((*sample)->subsamples, &alloc_size, >> + min_subsamples * >> sizeof(*subsamples)); > > The reason I did not comment on this block in the last mail is that > iiuc, the maximum allocation here is INT16_MAX * 8 which seems > acceptable (and there cannot be a realloc with the chosen initial > limit). Ok, changed back. > >> +sample_count = avio_rb32(pb); > > You have to check here... > > +for (i = 0; i < sample_count && !pb->eof_reached; i++) { > +unsigned int min_samples = FFMIN(FFMAX(i, 1024 * 1024), > sample_count); > +encrypted_samples = > av_fast_realloc(encryption_index->encrypted_samples, &alloc_size, > > +min_samples * > sizeof(*encrypted_samples)); > > ... if this product could overflow for the final reallocation, see 1112ba01. Done > > Thank you, Carl Eugen > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel From e8261628e11347a8aa1b61de04c53cc1174cdae3 Mon Sep 17 00:00:00 2001 From: Jacob Trimble Date: Wed, 6 Dec 2017 16:17:54 -0800 Subject: [PATCH 1/3] avformat/mov: Increase support for common encryption. - Parse schm atom to get different encryption schemes. - Allow senc atom to appear in track fragments. - Allow 16-byte IVs. - Allow constant IVs (specified in tenc). - Allow only tenc to specify encryption (i.e. no senc/saiz/saio). - Use sample descriptor to detect clear fragments. This doesn't support: - Different sample descriptor holding different encryption info. - Only first sample descriptor can be encrypted. - Encrypted sample groups (i.e. seig). - Non-'cenc' encryption scheme when using -decryption_key. This removes support for saio/saiz atoms, but it was incorrect before. A follow-up change will add correct support for those. Signed-off-by: Jacob Trimble --- libavformat/isom.h | 20 +- libavformat/mov.c | 432 ++--- tests/fate/mov.mak | 8 + tests/ref/fate/mov-frag-encrypted | 57 + tests/ref/fate/mov-tenc-only-encrypted | 57 + 5 files changed, 422 insertions(+), 152 deletions(-) create mode 100644 tests/ref/fate/mov-frag-encrypted create mode 100644 tests/ref/fate/mov-tenc-only-encrypted diff --git a/libavformat/isom.h b/libavformat/isom.h index 65676fb0f5..3794b1f0fd 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -27,6 +27,7 @@ #include #include +#include "libavutil/encryption_info.h" #
Re: [FFmpeg-devel] [PATCH 2/3] avformat/mov: Fix parsing of saio/siaz atoms in encrypted content.
On Mon, Jan 8, 2018 at 5:39 PM, Carl Eugen Hoyos wrote: > 2018-01-08 23:34 GMT+01:00 Jacob Trimble : >> On Fri, Jan 5, 2018 at 3:41 PM, Carl Eugen Hoyos wrote: >>> 2018-01-05 23:58 GMT+01:00 Jacob Trimble >>> : On Fri, Jan 5, 2018 at 2:01 PM, Carl Eugen Hoyos wrote: > 2018-01-05 22:29 GMT+01:00 Jacob Trimble > : >> On Fri, Jan 5, 2018 at 12:41 PM, Carl Eugen Hoyos >> wrote: >>> 2018-01-05 20:49 GMT+01:00 Jacob Trimble >>> : >>> +entry_count = avio_rb32(pb); +encryption_index->auxiliary_offsets = av_malloc_array(sizeof(size_t), entry_count); >>> >>> (sizeof(variable) instead of sizeof(type), please.) >>> >>> But since this could be used for a dos attack, please change this >>> to something similar to 1112ba01. >>> If it is easy to avoid it, very short files should not allocate >>> gigabytes. >> >> Switched to calculating the size based on the number of remaining >> bytes and returning an error if it doesn't match what is read. > > Sorry if I miss something: > >> +entry_count = (atom.size - 8 - (has_saio_type ? 8 : 0)) / (version >> == 0 ? 4 : 8); >> +if (avio_rb32(pb) != entry_count) { >> +av_log(c->fc, AV_LOG_ERROR, "incorrect entry_count in saio\n"); >> +return AVERROR_INVALIDDATA; >> +} >> +encryption_index->auxiliary_offsets = >> +av_malloc_array(sizeof(*encryption_index->auxiliary_offsets), >> entry_count); > > Does this avoid a 1G allocation for a file of a few bytes? > > Didn't you simply increase the number of needed bytes to change in a valid > mov file to behave maliciously from one to two? From what I can tell, the mov_read_default method (which is what reads child atoms) will verify "atom.size" to fit inside the parent atom. This means that for "atom.size" to be excessively large for the file size, the input would need to be non-seekable (since I think the top-level atom uses the file size) and all the atoms would need to have invalid sizes. >>> >>> (I did not check this but I am not convinced the sample I fixed last >>> week is so sophisticated.) >>> But technically I guess it is possible. >>> >>> Thank you. >>> But this is basically malloc some number of bytes then read that many bytes. The only alternative I can think of (in the face of non-seekable inputs) is to try-read in chunks until we hit EOF or the end of the expected size. This seems like a lot of extra work that is >>> not mirrored elsewhere. >>> >>> On the contrary. >>> >>> But you are right, I forgot to write that you have to add an "if (!eof)" >>> to the reading loops, see the function that above commit changed. >>> There are several cases where this isn't explicitly checked. >>> >>> Yes, and they will be fixed, please don't add another one. >>> Also, how does this attack work? If the number is way too big, well get EOM and error out. >>> >>> Which not only causes dos but also makes checking for other (if you >>> like: more dangerous) issues more difficult which is bad. We already >>> know that there are cases where the issue is hard to avoid, I believe >>> this is not such a case. >>> >>> It is possible to create (valid) samples that allocate a huge amount >>> of memory but very small files should not immediately allocate an >>> amount of several G. >> >> Done. > > +entry_count = avio_rb32(pb); > > This has to be checked for later overflow, same in other spots. Done > > +encryption_index->auxiliary_offsets = > +av_malloc_array(sizeof(*encryption_index->auxiliary_offsets), > entry_count); > > I believe you forgot to remove these two lines. Yep, done. > > Note that I chose "1024*1024" arbitrarily to avoid a speed-loss for > (most likely) all valid files when fixing the dos in 1112ba01. > I don't know what a good lower limit for your use-case can be, or > if only using av_fast_realloc() - without the high starting value - > makes sense. Ok, for the saio atoms, it will likely be small (changed it to 1024) since it will either be the number of tenc atoms or the number of chunks or 1. Later code actually only supports one offset, but I didn't want to hard-code that requirement here. > > Carl Eugen > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel From 76c6870513481c14c5c134f1b8e7e9a91e17e6b5 Mon Sep 17 00:00:00 2001 From: Jacob Trimble Date: Wed, 6 Dec 2017 16:17:54 -0800 Subject: [PATCH 2/3] avformat/mov: Fix parsing of saio/siaz atoms in encrypted content. This doesn't support saio atoms with more than one offset. Signed-off-by: Jacob Trimble --- libavformat/isom.h | 6 ++ libavformat/mov.c | 237 + 2 files changed, 243 insertions(+) diff
[FFmpeg-devel] GSoC 2018
Hi folks, yet again, the registration for Google Summer of Code 2018 has opened. Like in the previous years, we've setup an ideas page in our wiki: https://trac.ffmpeg.org/wiki/SponsoringPrograms/GSoC/2018 Same procedure as every year - we need to define more interesting tasks for students to apply for and fellow developers to mentor them. So please feel free to suggest a project and volunteer as mentor or backup mentor as you see fit. You are welcome to edit the wiki directly or just post your suggestion here. Please keep in mind that a potential student should be able to finish the project successfully in time. GSoC offers a lot of potential gain for FFmpeg as it brings in new contributors that might become active developers in our community afterwards. So dedicating some of our time to mentor as many projects as we should be in our best interest. The application deadline is January 23th which is exactly two weeks from now. Therefore, let's try to define new tasks soon. Thanks, Thilo ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 3/3] avformat/mov: Expose encryption info to the app.
On Mon, Jan 8, 2018 at 5:23 PM, Carl Eugen Hoyos wrote: > 2018-01-09 0:22 GMT+01:00 Jacob Trimble : > >> Updated with the new design for the side data and applied the realloc >> fix to avoid large allocations. > >> +kid_count = avio_rb32(pb); > > Missing check here ... > >> +for (; i < kid_count && !pb->eof_reached; i++) { >> +unsigned int min_kid_count = FFMIN(FFMAX(i, 1024), kid_count); >> +key_ids = av_fast_realloc(info->key_ids, &alloc_size, > >> + min_kid_count * sizeof(*key_ids)); > > ... for an overflow here. Done > > Thank you, Carl Eugen > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel From 92949de475a7fd1ede0959d452e3bf01b0a39b1f Mon Sep 17 00:00:00 2001 From: Jacob Trimble Date: Wed, 6 Dec 2017 16:17:54 -0800 Subject: [PATCH 3/3] avformat/mov: Expose encryption info to the app. This exposes encryption info from the container to the app. This includes key ID, IV, and subsample byte ranges. The info is passed using the new side-data AV_PKT_DATA_ENCRYPTION_DATA and AV_PKT_DATA_ENCRYPTION_INIT_DATA. Signed-off-by: Jacob Trimble --- libavformat/mov.c | 95 +++ 1 file changed, 95 insertions(+) diff --git a/libavformat/mov.c b/libavformat/mov.c index 750b8a0860..89cd550c12 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -6085,6 +6085,94 @@ static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom) return 0; } +static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom) +{ +AVEncryptionInitInfo *info; +uint8_t **key_ids; +AVStream *st; +uint8_t *side_data, *extra_data; +size_t side_data_size; +int ret = 0; +unsigned int version, kid_count, extra_data_size, alloc_size = 0, i = 0; + +if (c->fc->nb_streams < 1) +return 0; +st = c->fc->streams[c->fc->nb_streams-1]; + +version = avio_r8(pb); /* version */ +avio_rb24(pb); /* flags */ + +info = av_encryption_init_info_alloc(/* system_id_size */ 16, /* num_key_ids */ 0, + /* key_id_size */ 16, /* data_size */ 0); +if (!info) +return AVERROR(ENOMEM); + +if (avio_read(pb, info->system_id, 16) != 16) { +av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n"); +ret = AVERROR_INVALIDDATA; +goto finish; +} + +if (version > 0) { +kid_count = avio_rb32(pb); +if (kid_count >= INT_MAX / sizeof(*key_ids)) +return AVERROR(ENOMEM); + +for (; i < kid_count && !pb->eof_reached; i++) { +unsigned int min_kid_count = FFMIN(FFMAX(i, 1024), kid_count); +key_ids = av_fast_realloc(info->key_ids, &alloc_size, + min_kid_count * sizeof(*key_ids)); +if (!key_ids) { +ret = AVERROR(ENOMEM); +goto finish; +} +info->key_ids = key_ids; + +info->key_ids[i] = av_mallocz(16); +if (!info->key_ids[i]) { +ret = AVERROR(ENOMEM); +goto finish; +} +info->num_key_ids = i + 1; + +if (avio_read(pb, info->key_ids[i], 16) != 16) { +av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n"); +ret = AVERROR_INVALIDDATA; +goto finish; +} +} + +if (pb->eof_reached) { +av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading pssh\n"); +ret = AVERROR_INVALIDDATA; +goto finish; +} +} + +extra_data_size = avio_rb32(pb); +ret = mov_try_read_block(pb, extra_data_size, &extra_data); +if (ret < 0) +goto finish; + +av_freep(&info->data); // malloc(0) may still allocate something. +info->data = extra_data; +info->data_size = extra_data_size; + +side_data = av_encryption_init_info_add_side_data(info, &side_data_size); +if (!side_data) { +ret = AVERROR(ENOMEM); +goto finish; +} +ret = av_stream_add_side_data(st, AV_PKT_DATA_ENCRYPTION_INIT_INFO, + side_data, side_data_size); +if (ret < 0) +av_free(side_data); + +finish: +av_encryption_init_info_free(info); +return ret; +} + static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom) { AVStream *st; @@ -6324,6 +6412,12 @@ static int cenc_filter(MOVContext *mov, MOVStreamContext *sc, AVPacket *pkt, int if (mov->decryption_key) { return cenc_decrypt(mov, sc, encrypted_sample, pkt->data, pkt->size); +} else { +size_t size; +uint8_t *side_data = av_encryption_info_add_side_data(encrypted_sample, &size); +if (!side_data) +return AVERROR(ENOMEM); +return
Re: [FFmpeg-devel] [PATCH] avfilter/vf_overlay: add comment into eval_expr
On Tue, Jan 09, 2018 at 10:41:44AM +0800, Steven Liu wrote: > comment about the looks like a duplicate line. > but that is used to reason x is expressed from y > > Signed-off-by: Steven Liu > --- > libavfilter/vf_overlay.c | 1 + > 1 file changed, 1 insertion(+) LGTM, btw there were also other filters which do this [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Its not that you shouldnt use gotos but rather that you should write readable code and code with gotos often but not always is less readable signature.asc Description: PGP signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] Fix typo, use all coeffs in range for band tonality calculation
Hi. Current opusenc_psy code (step_collect_psy_metrics) uses only last coeff in range to calculate tone value. It looks like typo. -- Daniil Cherednik 0001-opusenc_psy-Typo-use-all-coeffs-in-range-for-band-to.patch Description: Binary data ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 5/5] aptx: add raw muxer and demuxer for aptX HD
On Sun, Jan 07, 2018 at 04:55:43PM +0100, Aurelien Jacobs wrote: > On Sun, Jan 07, 2018 at 12:53:27AM +0100, Michael Niedermayer wrote: > > On Sat, Jan 06, 2018 at 05:48:08PM +0100, Aurelien Jacobs wrote: > > > --- > > > Changelog| 2 +- > > > libavformat/Makefile | 2 ++ > > > libavformat/allformats.c | 1 + > > > libavformat/aptxdec.c| 51 > > > > > > libavformat/rawenc.c | 13 > > > 5 files changed, 64 insertions(+), 5 deletions(-) > > [...] > > > @@ -66,6 +94,7 @@ static const AVClass aptx_demuxer_class = { > > > .version= LIBAVUTIL_VERSION_INT, > > > }; > > > > > > +#if CONFIG_APTX_MUXER > > > AVInputFormat ff_aptx_demuxer = { > > > .name = "aptx", > > > .long_name = NULL_IF_CONFIG_SMALL("raw aptX"), > > > @@ -76,3 +105,17 @@ AVInputFormat ff_aptx_demuxer = { > > > .flags = AVFMT_GENERIC_INDEX, > > > > > .priv_class = &aptx_demuxer_class, > > [...] > > > +.priv_class = &aptx_demuxer_class, > > > > this cause the code (for example fate) to infinite loop > > Oh, indeed, it seems 2 demuxers can't share the same priv_class. > Here is an updated patch. yes, works here, no more comments from me [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB The real ebay dictionary, page 1 "Used only once"- "Some unspecified defect prevented a second use" "In good condition" - "Can be repaird by experienced expert" "As is" - "You wouldnt want it even if you were payed for it, if you knew ..." signature.asc Description: PGP signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 1/3] avcodec: v4l2_m2m: fix races around freeing data on close
On Tue, 9 Jan 2018 18:06:11 +0100 Jorge Ramirez-Ortiz wrote: > From: Mark Thompson > > Refcount all of the context information. This also fixes a potential > segmentation fault when accessing freed memory (buffer returned after > the codec has been closed). > > Tested-by: Jorge Ramirez-Ortiz > --- > libavcodec/v4l2_buffers.c | 32 ++-- > libavcodec/v4l2_buffers.h | 6 +++ > libavcodec/v4l2_m2m.c | 93 > +-- > libavcodec/v4l2_m2m.h | 35 ++ > libavcodec/v4l2_m2m_dec.c | 22 +++ > libavcodec/v4l2_m2m_enc.c | 22 +++ > 6 files changed, 140 insertions(+), 70 deletions(-) > > diff --git a/libavcodec/v4l2_buffers.c b/libavcodec/v4l2_buffers.c > index ba70c5d..4e68f90 100644 > --- a/libavcodec/v4l2_buffers.c > +++ b/libavcodec/v4l2_buffers.c > @@ -207,20 +207,17 @@ static void v4l2_free_buffer(void *opaque, uint8_t > *unused) > V4L2Buffer* avbuf = opaque; > V4L2m2mContext *s = buf_to_m2mctx(avbuf); > > -atomic_fetch_sub_explicit(&s->refcount, 1, memory_order_acq_rel); > -if (s->reinit) { > -if (!atomic_load(&s->refcount)) > -sem_post(&s->refsync); > -return; > -} > +if (atomic_fetch_sub(&avbuf->context_refcount, 1) == 1) { > +atomic_fetch_sub_explicit(&s->refcount, 1, memory_order_acq_rel); > > -if (avbuf->context->streamon) { > -ff_v4l2_buffer_enqueue(avbuf); > -return; > -} > +if (s->reinit) { > +if (!atomic_load(&s->refcount)) > +sem_post(&s->refsync); > +} else if (avbuf->context->streamon) > +ff_v4l2_buffer_enqueue(avbuf); > > -if (!atomic_load(&s->refcount)) > -ff_v4l2_m2m_codec_end(s->avctx); > +av_buffer_unref(&avbuf->context_ref); > +} > } > > static int v4l2_buf_to_bufref(V4L2Buffer *in, int plane, AVBufferRef **buf) > @@ -236,6 +233,17 @@ static int v4l2_buf_to_bufref(V4L2Buffer *in, int plane, > AVBufferRef **buf) > if (!*buf) > return AVERROR(ENOMEM); > > +if (in->context_ref) > +atomic_fetch_add(&in->context_refcount, 1); > +else { > +in->context_ref = av_buffer_ref(s->self_ref); > +if (!in->context_ref) { > +av_buffer_unref(buf); > +return AVERROR(ENOMEM); > +} > +in->context_refcount = 1; > +} > + > in->status = V4L2BUF_RET_USER; > atomic_fetch_add_explicit(&s->refcount, 1, memory_order_relaxed); > > diff --git a/libavcodec/v4l2_buffers.h b/libavcodec/v4l2_buffers.h > index e28a4a6..dc5cc9e 100644 > --- a/libavcodec/v4l2_buffers.h > +++ b/libavcodec/v4l2_buffers.h > @@ -24,6 +24,7 @@ > #ifndef AVCODEC_V4L2_BUFFERS_H > #define AVCODEC_V4L2_BUFFERS_H > > +#include > #include > > #include "avcodec.h" > @@ -41,6 +42,11 @@ typedef struct V4L2Buffer { > /* each buffer needs to have a reference to its context */ > struct V4L2Context *context; > > +/* This object is refcounted per-plane, so we need to keep track > + * of how many context-refs we are holding. */ > +AVBufferRef *context_ref; > +atomic_uint context_refcount; > + > /* keep track of the mmap address and mmap length */ > struct V4L2Plane_info { > int bytesperline; > diff --git a/libavcodec/v4l2_m2m.c b/libavcodec/v4l2_m2m.c > index 1d7a852..fd989ce 100644 > --- a/libavcodec/v4l2_m2m.c > +++ b/libavcodec/v4l2_m2m.c > @@ -222,8 +222,6 @@ int ff_v4l2_m2m_codec_reinit(V4L2m2mContext* s) > } > > /* 5. complete reinit */ > -sem_destroy(&s->refsync); > -sem_init(&s->refsync, 0, 0); > s->draining = 0; > s->reinit = 0; > > @@ -241,24 +239,26 @@ int ff_v4l2_m2m_codec_full_reinit(V4L2m2mContext *s) > if (atomic_load(&s->refcount)) > while(sem_wait(&s->refsync) == -1 && errno == EINTR); > > -/* close the driver */ > -ff_v4l2_m2m_codec_end(s->avctx); > +ret = ff_v4l2_context_set_status(&s->output, VIDIOC_STREAMOFF); > +if (ret) { > +av_log(s->avctx, AV_LOG_ERROR, "output VIDIOC_STREAMOFF\n"); > +goto error; > +} > + > +ret = ff_v4l2_context_set_status(&s->capture, VIDIOC_STREAMOFF); > +if (ret) { > +av_log(s->avctx, AV_LOG_ERROR, "capture VIDIOC_STREAMOFF\n"); > +goto error; > +} > + > +/* release and unmmap the buffers */ > +ff_v4l2_context_release(&s->output); > +ff_v4l2_context_release(&s->capture); > > /* start again now that we know the stream dimensions */ > s->draining = 0; > s->reinit = 0; > > -s->fd = open(s->devname, O_RDWR | O_NONBLOCK, 0); > -if (s->fd < 0) > -return AVERROR(errno); > - > -ret = v4l2_prepare_contexts(s); > -if (ret < 0) > -goto error; > - > -/* if a full re-init was requested - probe didn't run - we need to > populate > - * the format for each context > - */ > ret = ff_v4l2_context_get_format(
Re: [FFmpeg-devel] [PATCH] avformat/avio: fix off-by-one in retry_transfer_wrapper
On Tue, 9 Jan 2018 09:15:39 +0100 Martin Herkt wrote: > This reportedly fixes hangs with segmented streams. > Affects playback via Schannel on Windows in particular. > > Can be reproduced with any YouTube live stream. > --- > libavformat/avio.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/libavformat/avio.c b/libavformat/avio.c > index 63e82872f7..cd1e325a6b 100644 > --- a/libavformat/avio.c > +++ b/libavformat/avio.c > @@ -393,7 +393,7 @@ static inline int retry_transfer_wrapper(URLContext *h, > uint8_t *buf, > } > } else if (ret == AVERROR_EOF) > return (len > 0) ? len : AVERROR_EOF; > -else if (ret < 0) > +else if (ret <= 0) > return ret; > if (ret) { > fast_retries = FFMAX(fast_retries, 2); This was explicitly changed with the EOF change (that broke a lot of stuff), so this is probably not correct. The intention is very much to retry if the result is 0. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 1/3] avcodec: v4l2_m2m: fix races around freeing data on close
On 01/09/2018 08:36 PM, wm4 wrote: Yes, that seems much better conceptually. Though I wonder why there's still an atomic refcount left. that one is for the dynamic resolution change (a feature that is probably broken). I don't have the hardware I need to test it yet but will start to work on it since it is critical to many users. Also, can you send mail only to the mailing list? You CC a bunch of people and have yourself as part of the "To:" header, so I have to change the list of people I reply to every time since my dumb mail client can't figure it out itself. Not sure if others are inconvenienced by this as well - if not, feel free to ignore this ah yes, sorry I forgot. I remember you/someone mentioned last time I did this. I apologize. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avformat/aiffdec: AIFF fix in case of ANNO
On Mon, Jan 08, 2018 at 02:03:40PM +, endus...@gmail.com wrote: > From: Eduard Sinelnikov > > Apple's AIFF protocol clearly states that each chucnk which is odd sized a > padding should be added. > In the old version of aiffdec adding of padding was done in `get_meta`. And > in case of unknown chunk name it was done in defalut case. > The new version has deleted the padding in default case and added padding > adding after the switch. > But the new version didn't removed the padding adding in the `get_meta` > function so in some cases padding was added twice which leaded to a bug. do you have a testcase you can share that shows the probnlem ? or did you find the issue thorugh code review ? [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB It is dangerous to be right in matters on which the established authorities are wrong. -- Voltaire signature.asc Description: PGP signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 04/11] Preserve AFD side data when going from AVPacket to AVFrame
On Mon, Jan 08, 2018 at 08:16:51PM -0500, Devin Heitmueller wrote: > This is needed to ensure that AFD data continues to work when > capturing V210 video with the Decklink libavdevice input. > > Signed-off-by: Devin Heitmueller > --- > libavcodec/decode.c | 1 + > 1 file changed, 1 insertion(+) LGTM [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB You can kill me, but you cannot change the truth. signature.asc Description: PGP signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 2/3] avcodec: v4l2_m2m: remove unnecessary timeout.
--- a/libavcodec/v4l2_m2m_dec.c +++ b/libavcodec/v4l2_m2m_dec.c @@ -131,14 +131,22 @@ static int v4l2_receive_frame(AVCodecContext *avctx, AVFrame *frame) V4L2Context *const capture = &s->capture; V4L2Context *const output = &s->output; AVPacket avpkt = {0}; -int ret; +int i, ret; ret = ff_decode_get_packet(avctx, &avpkt); if (ret < 0 && ret != AVERROR_EOF) return ret; -if (s->draining) -goto dequeue; +if (s->draining) { +for (i = 0; i < capture->num_buffers; i++) { +if (capture->buffers[i].status == V4L2BUF_IN_DRIVER) +goto dequeue; +} + +/* no more buffers in the driver, we are done */ +capture->done = 1; +return AVERROR_EOF; +} ret = ff_v4l2_context_enqueue_packet(output, &avpkt); if (ret < 0) { diff --git a/libavcodec/v4l2_m2m_enc.c b/libavcodec/v4l2_m2m_enc.c index 4c9ea1f..3d7c241 100644 --- a/libavcodec/v4l2_m2m_enc.c +++ b/libavcodec/v4l2_m2m_enc.c @@ -253,10 +253,18 @@ static int v4l2_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) V4L2m2mContext *s = ((V4L2m2mPriv*)avctx->priv_data)->context; V4L2Context *const capture = &s->capture; V4L2Context *const output = &s->output; -int ret; +int i, ret; + +if (s->draining) { um, I shouldnt be exposing this information in this file. I'll push it back to v4l2_context at the time of dequeue instead so the interface remains clean and I dont duplicate the code in the decoder please ignore this patch +for (i = 0; i < capture->num_buffers; i++) { +if (capture->buffers[i].status == V4L2BUF_IN_DRIVER) +goto dequeue; +} -if (s->draining) -goto dequeue; +/* no more buffers in the driver, we are done */ +capture->done = 1; +return AVERROR_EOF; +} if (!output->streamon) { ret = ff_v4l2_context_set_status(output, VIDIOC_STREAMON); ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 3/3] avcodec: v4l2_m2m: context: fix raising warning on POLLERR
On 01/09/2018 06:06 PM, Jorge Ramirez-Ortiz wrote: From: Jorge Ramirez-Ortiz During the initialization stage, the codec attempts to get free buffers from the driver before any have been queued (this is to keep the code simple and generic) When the kernel driver detects this situation, it returns POLLERR in revents and ffmpeg therefore raises a warning. This commit disables the warning since no buffers were queued to the driver yet. Signed-off-by: Jorge Ramirez-Ortiz --- libavcodec/v4l2_context.c | 16 ++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/libavcodec/v4l2_context.c b/libavcodec/v4l2_context.c index fb482cf..5bacaaf 100644 --- a/libavcodec/v4l2_context.c +++ b/libavcodec/v4l2_context.c @@ -258,7 +258,7 @@ static V4L2Buffer* v4l2_dequeue_v4l2buf(V4L2Context *ctx, int timeout) .events = POLLIN | POLLRDNORM | POLLPRI | POLLOUT | POLLWRNORM, /* default blocking capture */ .fd = ctx_to_m2mctx(ctx)->fd, }; -int ret; +int i, ret; if (V4L2_TYPE_IS_OUTPUT(ctx->type)) pfd.events = POLLOUT | POLLWRNORM; @@ -279,7 +279,19 @@ static V4L2Buffer* v4l2_dequeue_v4l2buf(V4L2Context *ctx, int timeout) /* 0. handle errors */ if (pfd.revents & POLLERR) { -av_log(logger(ctx), AV_LOG_WARNING, "%s POLLERR\n", ctx->name); + /* if we are trying to get free buffers but none have been queued yet + no need to raise a warning */ sorry about the linux tabs (my editor messed it up, my fault) will fix. + if (timeout == 0 ) { + for (i = 0; i < ctx->num_buffers; i++) { + if (ctx->buffers[i].status != V4L2BUF_AVAILABLE) { + av_log(logger(ctx), AV_LOG_WARNING, "%s POLLERR\n", ctx->name); + return NULL; + } + } + } + else + av_log(logger(ctx), AV_LOG_WARNING, "%s POLLERR\n", ctx->name); + return NULL; } ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/3] avcodec: v4l2_m2m: fix races around freeing data on close
From: Mark Thompson Refcount all of the context information. This also fixes a potential segmentation fault when accessing freed memory (buffer returned after the codec has been closed). Tested-by: Jorge Ramirez-Ortiz --- libavcodec/v4l2_buffers.c | 32 ++-- libavcodec/v4l2_buffers.h | 6 +++ libavcodec/v4l2_m2m.c | 93 +-- libavcodec/v4l2_m2m.h | 35 ++ libavcodec/v4l2_m2m_dec.c | 22 +++ libavcodec/v4l2_m2m_enc.c | 22 +++ 6 files changed, 140 insertions(+), 70 deletions(-) diff --git a/libavcodec/v4l2_buffers.c b/libavcodec/v4l2_buffers.c index ba70c5d..4e68f90 100644 --- a/libavcodec/v4l2_buffers.c +++ b/libavcodec/v4l2_buffers.c @@ -207,20 +207,17 @@ static void v4l2_free_buffer(void *opaque, uint8_t *unused) V4L2Buffer* avbuf = opaque; V4L2m2mContext *s = buf_to_m2mctx(avbuf); -atomic_fetch_sub_explicit(&s->refcount, 1, memory_order_acq_rel); -if (s->reinit) { -if (!atomic_load(&s->refcount)) -sem_post(&s->refsync); -return; -} +if (atomic_fetch_sub(&avbuf->context_refcount, 1) == 1) { +atomic_fetch_sub_explicit(&s->refcount, 1, memory_order_acq_rel); -if (avbuf->context->streamon) { -ff_v4l2_buffer_enqueue(avbuf); -return; -} +if (s->reinit) { +if (!atomic_load(&s->refcount)) +sem_post(&s->refsync); +} else if (avbuf->context->streamon) +ff_v4l2_buffer_enqueue(avbuf); -if (!atomic_load(&s->refcount)) -ff_v4l2_m2m_codec_end(s->avctx); +av_buffer_unref(&avbuf->context_ref); +} } static int v4l2_buf_to_bufref(V4L2Buffer *in, int plane, AVBufferRef **buf) @@ -236,6 +233,17 @@ static int v4l2_buf_to_bufref(V4L2Buffer *in, int plane, AVBufferRef **buf) if (!*buf) return AVERROR(ENOMEM); +if (in->context_ref) +atomic_fetch_add(&in->context_refcount, 1); +else { +in->context_ref = av_buffer_ref(s->self_ref); +if (!in->context_ref) { +av_buffer_unref(buf); +return AVERROR(ENOMEM); +} +in->context_refcount = 1; +} + in->status = V4L2BUF_RET_USER; atomic_fetch_add_explicit(&s->refcount, 1, memory_order_relaxed); diff --git a/libavcodec/v4l2_buffers.h b/libavcodec/v4l2_buffers.h index e28a4a6..dc5cc9e 100644 --- a/libavcodec/v4l2_buffers.h +++ b/libavcodec/v4l2_buffers.h @@ -24,6 +24,7 @@ #ifndef AVCODEC_V4L2_BUFFERS_H #define AVCODEC_V4L2_BUFFERS_H +#include #include #include "avcodec.h" @@ -41,6 +42,11 @@ typedef struct V4L2Buffer { /* each buffer needs to have a reference to its context */ struct V4L2Context *context; +/* This object is refcounted per-plane, so we need to keep track + * of how many context-refs we are holding. */ +AVBufferRef *context_ref; +atomic_uint context_refcount; + /* keep track of the mmap address and mmap length */ struct V4L2Plane_info { int bytesperline; diff --git a/libavcodec/v4l2_m2m.c b/libavcodec/v4l2_m2m.c index 1d7a852..fd989ce 100644 --- a/libavcodec/v4l2_m2m.c +++ b/libavcodec/v4l2_m2m.c @@ -222,8 +222,6 @@ int ff_v4l2_m2m_codec_reinit(V4L2m2mContext* s) } /* 5. complete reinit */ -sem_destroy(&s->refsync); -sem_init(&s->refsync, 0, 0); s->draining = 0; s->reinit = 0; @@ -241,24 +239,26 @@ int ff_v4l2_m2m_codec_full_reinit(V4L2m2mContext *s) if (atomic_load(&s->refcount)) while(sem_wait(&s->refsync) == -1 && errno == EINTR); -/* close the driver */ -ff_v4l2_m2m_codec_end(s->avctx); +ret = ff_v4l2_context_set_status(&s->output, VIDIOC_STREAMOFF); +if (ret) { +av_log(s->avctx, AV_LOG_ERROR, "output VIDIOC_STREAMOFF\n"); +goto error; +} + +ret = ff_v4l2_context_set_status(&s->capture, VIDIOC_STREAMOFF); +if (ret) { +av_log(s->avctx, AV_LOG_ERROR, "capture VIDIOC_STREAMOFF\n"); +goto error; +} + +/* release and unmmap the buffers */ +ff_v4l2_context_release(&s->output); +ff_v4l2_context_release(&s->capture); /* start again now that we know the stream dimensions */ s->draining = 0; s->reinit = 0; -s->fd = open(s->devname, O_RDWR | O_NONBLOCK, 0); -if (s->fd < 0) -return AVERROR(errno); - -ret = v4l2_prepare_contexts(s); -if (ret < 0) -goto error; - -/* if a full re-init was requested - probe didn't run - we need to populate - * the format for each context - */ ret = ff_v4l2_context_get_format(&s->output); if (ret) { av_log(log_ctx, AV_LOG_DEBUG, "v4l2 output format not supported\n"); @@ -301,19 +301,25 @@ int ff_v4l2_m2m_codec_full_reinit(V4L2m2mContext *s) return 0; error: -if (close(s->fd) < 0) { -ret = AVERROR(errno); -av_log(log_ctx, AV_LOG_ERROR, "error closing %s (%s)\n", -s->devname, av
[FFmpeg-devel] [PATCH v1 2/3] avcodec: v4l2_m2m: remove unnecessary timeout.
From: Jorge Ramirez-Ortiz Qualcomm's db410c/db820 Venus driver currently present in mainline kernel has a bug which mishandles the CMD_STOP requests causing the decoder to block while draining [1]. This patch removes the workaround that was used to prevent that situation. Encoding/Decoding tested on db820c. [1] on CMD_STOP, the driver is flushing all buffers and never raising IPIPE which ends up in blocking on poll. --- libavcodec/v4l2_buffers.c | 10 ++-- libavcodec/v4l2_context.c | 61 --- 2 files changed, 44 insertions(+), 27 deletions(-) diff --git a/libavcodec/v4l2_buffers.c b/libavcodec/v4l2_buffers.c index 4e68f90..8e4d4d1 100644 --- a/libavcodec/v4l2_buffers.c +++ b/libavcodec/v4l2_buffers.c @@ -213,8 +213,14 @@ static void v4l2_free_buffer(void *opaque, uint8_t *unused) if (s->reinit) { if (!atomic_load(&s->refcount)) sem_post(&s->refsync); -} else if (avbuf->context->streamon) -ff_v4l2_buffer_enqueue(avbuf); +} else { +if (s->draining) { +/* no need to queue more buffers to the driver */ +avbuf->status = V4L2BUF_AVAILABLE; +} +else if (avbuf->context->streamon) +ff_v4l2_buffer_enqueue(avbuf); +} av_buffer_unref(&avbuf->context_ref); } diff --git a/libavcodec/v4l2_context.c b/libavcodec/v4l2_context.c index 4c16992..dde97d0 100644 --- a/libavcodec/v4l2_context.c +++ b/libavcodec/v4l2_context.c @@ -217,6 +217,7 @@ static int v4l2_stop_decode(V4L2Context *ctx) { struct v4l2_decoder_cmd cmd = { .cmd = V4L2_DEC_CMD_STOP, +.flags = 0, }; int ret; @@ -234,6 +235,7 @@ static int v4l2_stop_encode(V4L2Context *ctx) { struct v4l2_encoder_cmd cmd = { .cmd = V4L2_ENC_CMD_STOP, +.flags = 0, }; int ret; @@ -256,10 +258,26 @@ static V4L2Buffer* v4l2_dequeue_v4l2buf(V4L2Context *ctx, int timeout) .events = POLLIN | POLLRDNORM | POLLPRI | POLLOUT | POLLWRNORM, /* default blocking capture */ .fd = ctx_to_m2mctx(ctx)->fd, }; -int ret; +int i, ret; + +/* if we are draining and there are no more capture buffers queued in the driver we are done */ +if (!V4L2_TYPE_IS_OUTPUT(ctx->type) && ctx_to_m2mctx(ctx)->draining) { +for (i = 0; i < ctx->num_buffers; i++) { +if (ctx->buffers[i].status == V4L2BUF_IN_DRIVER) +goto start; +} +ctx->done = 1; +return NULL; +} +start: if (V4L2_TYPE_IS_OUTPUT(ctx->type)) pfd.events = POLLOUT | POLLWRNORM; +else { +/* no need to listen to requests for more input while draining */ +if (ctx_to_m2mctx(ctx)->draining) +pfd.events = POLLIN | POLLRDNORM | POLLPRI; +} for (;;) { ret = poll(&pfd, 1, timeout); @@ -267,11 +285,6 @@ static V4L2Buffer* v4l2_dequeue_v4l2buf(V4L2Context *ctx, int timeout) break; if (errno == EINTR) continue; - -/* timeout is being used to indicate last valid bufer when draining */ -if (ctx_to_m2mctx(ctx)->draining) -ctx->done = 1; - return NULL; } @@ -286,7 +299,7 @@ static V4L2Buffer* v4l2_dequeue_v4l2buf(V4L2Context *ctx, int timeout) ret = v4l2_handle_event(ctx); if (ret < 0) { /* if re-init failed, abort */ -ctx->done = EINVAL; +ctx->done = 1; return NULL; } if (ret) { @@ -325,23 +338,25 @@ dequeue: ret = ioctl(ctx_to_m2mctx(ctx)->fd, VIDIOC_DQBUF, &buf); if (ret) { if (errno != EAGAIN) { -ctx->done = errno; +ctx->done = 1; if (errno != EPIPE) av_log(logger(ctx), AV_LOG_DEBUG, "%s VIDIOC_DQBUF, errno (%s)\n", ctx->name, av_err2str(AVERROR(errno))); } -} else { -avbuf = &ctx->buffers[buf.index]; -avbuf->status = V4L2BUF_AVAILABLE; -avbuf->buf = buf; -if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) { -memcpy(avbuf->planes, planes, sizeof(planes)); -avbuf->buf.m.planes = avbuf->planes; -} +return NULL; } + +avbuf = &ctx->buffers[buf.index]; +avbuf->status = V4L2BUF_AVAILABLE; +avbuf->buf = buf; +if (V4L2_TYPE_IS_MULTIPLANAR(ctx->type)) { +memcpy(avbuf->planes, planes, sizeof(planes)); +avbuf->buf.m.planes = avbuf->planes; +} +return avbuf; } -return avbuf; +return NULL; } static V4L2Buffer* v4l2_getfree_v4l2buf(V4L2Context *ctx) @@ -552,14 +567,12 @@ int ff_v4l2_context_dequeue_frame(V4L2Context* ctx, AVFrame* frame) { V4L2Buffer* avbuf = NULL; -/* if we are draining, we are no longer inp
[FFmpeg-devel] [PATCH v1 3/3] avcodec: v4l2_m2m: context: fix raising warning on POLLERR
From: Jorge Ramirez-Ortiz During the initialization stage, the codec attempts to get free buffers from the driver before any have been queued (this is to keep the code simple and generic) When the kernel driver detects this situation, it returns POLLERR in revents and ffmpeg therefore raises a warning. This commit disables the warning since no buffers were queued to the driver yet. Signed-off-by: Jorge Ramirez-Ortiz --- libavcodec/v4l2_context.c | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/libavcodec/v4l2_context.c b/libavcodec/v4l2_context.c index dde97d0..e0431b1 100644 --- a/libavcodec/v4l2_context.c +++ b/libavcodec/v4l2_context.c @@ -290,7 +290,17 @@ start: /* 0. handle errors */ if (pfd.revents & POLLERR) { -av_log(logger(ctx), AV_LOG_WARNING, "%s POLLERR\n", ctx->name); +/* if we are trying to get free buffers but none have been queued yet + no need to raise a warning */ +if (timeout == 0) { +for (i = 0; i < ctx->num_buffers; i++) { +if (ctx->buffers[i].status != V4L2BUF_AVAILABLE) +av_log(logger(ctx), AV_LOG_WARNING, "%s POLLERR\n", ctx->name); +} +} +else +av_log(logger(ctx), AV_LOG_WARNING, "%s POLLERR\n", ctx->name); + return NULL; } -- 2.7.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH v1 1/3] avcodec: v4l2_m2m: fix races around freeing data on close
From: Mark Thompson Refcount all of the context information. This also fixes a potential segmentation fault when accessing freed memory (buffer returned after the codec has been closed). Tested-by: Jorge Ramirez-Ortiz --- libavcodec/v4l2_buffers.c | 32 ++-- libavcodec/v4l2_buffers.h | 6 +++ libavcodec/v4l2_m2m.c | 93 +-- libavcodec/v4l2_m2m.h | 35 ++ libavcodec/v4l2_m2m_dec.c | 22 +++ libavcodec/v4l2_m2m_enc.c | 22 +++ 6 files changed, 140 insertions(+), 70 deletions(-) diff --git a/libavcodec/v4l2_buffers.c b/libavcodec/v4l2_buffers.c index ba70c5d..4e68f90 100644 --- a/libavcodec/v4l2_buffers.c +++ b/libavcodec/v4l2_buffers.c @@ -207,20 +207,17 @@ static void v4l2_free_buffer(void *opaque, uint8_t *unused) V4L2Buffer* avbuf = opaque; V4L2m2mContext *s = buf_to_m2mctx(avbuf); -atomic_fetch_sub_explicit(&s->refcount, 1, memory_order_acq_rel); -if (s->reinit) { -if (!atomic_load(&s->refcount)) -sem_post(&s->refsync); -return; -} +if (atomic_fetch_sub(&avbuf->context_refcount, 1) == 1) { +atomic_fetch_sub_explicit(&s->refcount, 1, memory_order_acq_rel); -if (avbuf->context->streamon) { -ff_v4l2_buffer_enqueue(avbuf); -return; -} +if (s->reinit) { +if (!atomic_load(&s->refcount)) +sem_post(&s->refsync); +} else if (avbuf->context->streamon) +ff_v4l2_buffer_enqueue(avbuf); -if (!atomic_load(&s->refcount)) -ff_v4l2_m2m_codec_end(s->avctx); +av_buffer_unref(&avbuf->context_ref); +} } static int v4l2_buf_to_bufref(V4L2Buffer *in, int plane, AVBufferRef **buf) @@ -236,6 +233,17 @@ static int v4l2_buf_to_bufref(V4L2Buffer *in, int plane, AVBufferRef **buf) if (!*buf) return AVERROR(ENOMEM); +if (in->context_ref) +atomic_fetch_add(&in->context_refcount, 1); +else { +in->context_ref = av_buffer_ref(s->self_ref); +if (!in->context_ref) { +av_buffer_unref(buf); +return AVERROR(ENOMEM); +} +in->context_refcount = 1; +} + in->status = V4L2BUF_RET_USER; atomic_fetch_add_explicit(&s->refcount, 1, memory_order_relaxed); diff --git a/libavcodec/v4l2_buffers.h b/libavcodec/v4l2_buffers.h index e28a4a6..dc5cc9e 100644 --- a/libavcodec/v4l2_buffers.h +++ b/libavcodec/v4l2_buffers.h @@ -24,6 +24,7 @@ #ifndef AVCODEC_V4L2_BUFFERS_H #define AVCODEC_V4L2_BUFFERS_H +#include #include #include "avcodec.h" @@ -41,6 +42,11 @@ typedef struct V4L2Buffer { /* each buffer needs to have a reference to its context */ struct V4L2Context *context; +/* This object is refcounted per-plane, so we need to keep track + * of how many context-refs we are holding. */ +AVBufferRef *context_ref; +atomic_uint context_refcount; + /* keep track of the mmap address and mmap length */ struct V4L2Plane_info { int bytesperline; diff --git a/libavcodec/v4l2_m2m.c b/libavcodec/v4l2_m2m.c index 1d7a852..fd989ce 100644 --- a/libavcodec/v4l2_m2m.c +++ b/libavcodec/v4l2_m2m.c @@ -222,8 +222,6 @@ int ff_v4l2_m2m_codec_reinit(V4L2m2mContext* s) } /* 5. complete reinit */ -sem_destroy(&s->refsync); -sem_init(&s->refsync, 0, 0); s->draining = 0; s->reinit = 0; @@ -241,24 +239,26 @@ int ff_v4l2_m2m_codec_full_reinit(V4L2m2mContext *s) if (atomic_load(&s->refcount)) while(sem_wait(&s->refsync) == -1 && errno == EINTR); -/* close the driver */ -ff_v4l2_m2m_codec_end(s->avctx); +ret = ff_v4l2_context_set_status(&s->output, VIDIOC_STREAMOFF); +if (ret) { +av_log(s->avctx, AV_LOG_ERROR, "output VIDIOC_STREAMOFF\n"); +goto error; +} + +ret = ff_v4l2_context_set_status(&s->capture, VIDIOC_STREAMOFF); +if (ret) { +av_log(s->avctx, AV_LOG_ERROR, "capture VIDIOC_STREAMOFF\n"); +goto error; +} + +/* release and unmmap the buffers */ +ff_v4l2_context_release(&s->output); +ff_v4l2_context_release(&s->capture); /* start again now that we know the stream dimensions */ s->draining = 0; s->reinit = 0; -s->fd = open(s->devname, O_RDWR | O_NONBLOCK, 0); -if (s->fd < 0) -return AVERROR(errno); - -ret = v4l2_prepare_contexts(s); -if (ret < 0) -goto error; - -/* if a full re-init was requested - probe didn't run - we need to populate - * the format for each context - */ ret = ff_v4l2_context_get_format(&s->output); if (ret) { av_log(log_ctx, AV_LOG_DEBUG, "v4l2 output format not supported\n"); @@ -301,19 +301,25 @@ int ff_v4l2_m2m_codec_full_reinit(V4L2m2mContext *s) return 0; error: -if (close(s->fd) < 0) { -ret = AVERROR(errno); -av_log(log_ctx, AV_LOG_ERROR, "error closing %s (%s)\n", -s->devname, av
[FFmpeg-devel] [PATCH] add dumpwave filter
From: Dmytro Humeniuk Signed-off-by: Dmytro Humeniuk --- Changelog | 1 + doc/filters.texi | 23 libavfilter/Makefile | 1 + libavfilter/af_dumpwave.c | 285 + libavfilter/allfilters.c | 1 + libavfilter/version.h | 4 +- tests/fate/filter-audio.mak| 5 + tests/ref/fate/filter-dumpwave | 1 + 8 files changed, 319 insertions(+), 2 deletions(-) create mode 100644 libavfilter/af_dumpwave.c create mode 100644 tests/ref/fate/filter-dumpwave diff --git a/Changelog b/Changelog index 61075b3392..40fd624449 100644 --- a/Changelog +++ b/Changelog @@ -38,6 +38,7 @@ version : - Removed the ffserver program - Removed the ffmenc and ffmdec muxer and demuxer - VideoToolbox HEVC encoder and hwaccel +- dumpwave audio filter version 3.4: diff --git a/doc/filters.texi b/doc/filters.texi index d29c40080f..98e54aec6e 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -2529,6 +2529,29 @@ Optional. It should have a value much less than 1 (e.g. 0.05 or 0.02) and is used to prevent clipping. @end table +@section dumpwave +Dumps RMS amplitude to JSON file. +Converts samples to decibels and calculates RMS (Root-Mean-Square) audio power scaled to desired values. + +@table @option +@item d +Dimensions @code{WxH}. +@code{W} - number of data values in json, values will be scaled according to @code{H}. +The default value is @var{640x480} + +@item s +Samples count per value per channel + +@item json +Path to json file +@end table + +For example, to generate RMS amplitude for 44.1 kHz 6 seconds length audio +with dimensions @var{1800x140}, samples count @code{44100*6/1800=147} and store it to @var{/tmp/out.json}, you might use: +@example +dumpwave=d=1800x140:s=147:json=/tmp/out.json +@end example + @section dynaudnorm Dynamic Audio Normalizer. diff --git a/libavfilter/Makefile b/libavfilter/Makefile index ef4729dd3f..2ffbc9497a 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -87,6 +87,7 @@ OBJS-$(CONFIG_COMPENSATIONDELAY_FILTER) += af_compensationdelay.o OBJS-$(CONFIG_CROSSFEED_FILTER) += af_crossfeed.o OBJS-$(CONFIG_CRYSTALIZER_FILTER)+= af_crystalizer.o OBJS-$(CONFIG_DCSHIFT_FILTER)+= af_dcshift.o +OBJS-$(CONFIG_DUMPWAVE_FILTER) += af_dumpwave.o OBJS-$(CONFIG_DYNAUDNORM_FILTER) += af_dynaudnorm.o OBJS-$(CONFIG_EARWAX_FILTER) += af_earwax.o OBJS-$(CONFIG_EBUR128_FILTER)+= f_ebur128.o diff --git a/libavfilter/af_dumpwave.c b/libavfilter/af_dumpwave.c new file mode 100644 index 00..a1aa33d090 --- /dev/null +++ b/libavfilter/af_dumpwave.c @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2017 Dmytro Humeniuk + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * waveform audio filter – dumps RMS amplitude to JSON file like SoundCloud does + */ + +#include "libavutil/avassert.h" +#include "libavutil/avstring.h" +#include "libavutil/channel_layout.h" +#include "libavutil/opt.h" +#include "libavutil/parseutils.h" +#include "avfilter.h" +#include "formats.h" +#include "audio.h" +#include "internal.h" + +typedef struct DumpWaveContext { +const AVClass *class; /**< class for AVOptions */ +int w; /**< number of data values in json */ +int h; /**< values will be scaled according to provided */ +int is_disabled;/**< disable filter in case it's misconfigured */ +int i; /**< index of value */ +char *json; /**< path to json */ +char *str; /**< comma separated values */ +double *values; /**< scaling factors */ +int64_t s; /**< samples per value per channel */ +int64_t n; /**< current number of samples counted */ +int64_t max_samples;/**< samples per value */ +double sum; /**< sum of the squared samples per value */ +} DumpWaveContext; + +#define OFFSET(x) offsetof(DumpWaveContext, x) +#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM + +static const AVOption dumpwave_options[] = { +{ "d", "set width and height", OFFSET(w), AV_OPT_TYPE_IMAGE_SI
Re: [FFmpeg-devel] [PATCH] avfilter: add dumpwave filter.
Hi, >Can you provide some context for this? Please add docs as well. filter converts samples to decibels and calculates RMS (Root-Mean-Square) audio power scaled to desired values, it supposed to generate something like SoundCloud does http://plnkr.co/edit/WeppGcEPQiOyKDsA0C4Y I added docs. >Can't really test this because it segfaults for me: ./ffmpeg -f lavfi >-i anoisesrc -af dumpwave -f null - it expected some config - fixed >Just set the sample format to something like AV_SAMPLE_FMT_DBL in >query_format. There's no need for this big switch statement. it handles samples in different way, you may look at the astats filter 2018-01-08 23:58 GMT+01:00 Kyle Swanson : > Hi, > > Can you provide some context for this? Please add docs as well. > Can't really test this because it segfaults for me: ./ffmpeg -f lavfi > -i anoisesrc -af dumpwave -f null - > > On Sun, Jan 7, 2018 at 4:36 PM, wrote: >> >> From: Dmytro Humeniuk >> >> Signed-off-by: Dmytro Humeniuk >> --- >> Changelog | 1 + >> libavfilter/Makefile | 1 + >> libavfilter/af_dumpwave.c | 273 >> + >> libavfilter/allfilters.c | 1 + >> libavfilter/version.h | 4 +- >> tests/fate/filter-audio.mak| 5 + >> tests/ref/fate/filter-dumpwave | 1 + >> 7 files changed, 284 insertions(+), 2 deletions(-) >> create mode 100644 libavfilter/af_dumpwave.c >> create mode 100644 tests/ref/fate/filter-dumpwave >> >> diff --git a/Changelog b/Changelog >> index 61075b3392..40fd624449 100644 >> --- a/Changelog >> +++ b/Changelog >> @@ -38,6 +38,7 @@ version : >> - Removed the ffserver program >> - Removed the ffmenc and ffmdec muxer and demuxer >> - VideoToolbox HEVC encoder and hwaccel >> +- dumpwave audio filter >> >> >> version 3.4: >> diff --git a/libavfilter/Makefile b/libavfilter/Makefile >> index 256dfabd66..020d90ee01 100644 >> --- a/libavfilter/Makefile >> +++ b/libavfilter/Makefile >> @@ -122,6 +122,7 @@ OBJS-$(CONFIG_TREMOLO_FILTER)+= >> af_tremolo.o >> OBJS-$(CONFIG_VIBRATO_FILTER)+= af_vibrato.o >> generate_wave_table.o >> OBJS-$(CONFIG_VOLUME_FILTER) += af_volume.o >> OBJS-$(CONFIG_VOLUMEDETECT_FILTER) += af_volumedetect.o >> +OBJS-$(CONFIG_DUMPWAVE_FILTER) += af_dumpwave.o >> >> OBJS-$(CONFIG_AEVALSRC_FILTER) += aeval.o >> OBJS-$(CONFIG_ANOISESRC_FILTER) += asrc_anoisesrc.o >> diff --git a/libavfilter/af_dumpwave.c b/libavfilter/af_dumpwave.c >> new file mode 100644 >> index 00..493b5b7ff2 >> --- /dev/null >> +++ b/libavfilter/af_dumpwave.c >> @@ -0,0 +1,273 @@ >> +/* >> + * Copyright (c) 2017 Dmytro Humeniuk >> + * >> + * This file is part of FFmpeg. >> + * >> + * FFmpeg is free software; you can redistribute it and/or >> + * modify it under the terms of the GNU Lesser General Public >> + * License as published by the Free Software Foundation; either >> + * version 2.1 of the License, or (at your option) any later version. >> + * >> + * FFmpeg is distributed in the hope that it will be useful, >> + * but WITHOUT ANY WARRANTY; without even the implied warranty of >> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >> + * Lesser General Public License for more details. >> + * >> + * You should have received a copy of the GNU Lesser General Public >> + * License along with FFmpeg; if not, write to the Free Software >> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 >> USA >> + */ >> + >> +/** >> + * @file >> + * waveform audio filter – dumps RMS amplitude to JSON file like SoundCloud >> does >> + */ >> + >> +#include "libavutil/avassert.h" >> +#include "libavutil/avstring.h" >> +#include "libavutil/channel_layout.h" >> +#include "libavutil/opt.h" >> +#include "libavutil/parseutils.h" >> +#include "avfilter.h" >> +#include "formats.h" >> +#include "audio.h" >> +#include "internal.h" >> + >> +typedef struct DumpWaveContext { >> +const AVClass *class; >> +int w, h; >> +AVRational rate; >> +int col; >> +char *json; >> +char *str; >> +double *values; >> +int64_t c, n, max_samples; >> +double sum; /* sum of the squared samples per segment */ >> +} DumpWaveContext; >> + >> +#define OFFSET(x) offsetof(DumpWaveContext, x) >> +#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM >> + >> +static const AVOption dumpwave_options[] = { >> +{ "s","set dump size", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = >> "600x240"}, 0, 0, FLAGS }, >> +{ "c", "set number of samples per item", OFFSET(c), AV_OPT_TYPE_INT64, >> {.i64 = 0}, 0, INT64_MAX, FLAGS }, > > Use more descriptive parameter names. Also, per item? What is an item? > >> +{ "json", "set dump file", OFFSET(json), AV_OPT_TYPE_STRING, { .str = >> NULL }, 0, 0, FLAGS }, >> +{ NULL } >> +}; >> + >> +AVFILTER_DEFINE_CLASS(dumpwave); >> + >> +static int config_output(AVFilterL
Re: [FFmpeg-devel] [PATCH 1/2] lavf/http.c: Free allocated client URLContext in case of error.
On Sat, May 20, 2017 at 2:50 AM, Stephan Holljes wrote: > On Sat, Apr 22, 2017 at 3:18 AM, Stephan Holljes > wrote: >> On Tue, Apr 11, 2017 at 8:05 PM, Stephan Holljes >> wrote: >>> --- >>> >>> This version returns 0 in case of success and does not fallthrough to fail:. >>> >>> libavformat/http.c | 4 >>> 1 file changed, 4 insertions(+) >>> >>> diff --git a/libavformat/http.c b/libavformat/http.c >>> index 293a8a7..2917b6e 100644 >>> --- a/libavformat/http.c >>> +++ b/libavformat/http.c >>> @@ -535,7 +535,11 @@ static int http_accept(URLContext *s, URLContext **c) >>> goto fail; >>> cc->hd = cl; >>> cc->is_multi_client = 1; >>> +return 0; >>> fail: >>> +if (c) { >>> +ffurl_close(*c); >>> +} >>> return ret; >>> } >>> >>> -- >>> 2.9.3 >>> >> >> Friendly ping :) > > Ping. These patches still seem to apply, ping :) ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH v2 2/3] avdevice/decklink: addition of PTS_SRC_NB in enum DecklinkPtsSource
From: Vishwanath Dixit --- libavdevice/decklink_common_c.h | 1 + libavdevice/decklink_dec_c.c| 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/libavdevice/decklink_common_c.h b/libavdevice/decklink_common_c.h index ac6563a..18097e2 100644 --- a/libavdevice/decklink_common_c.h +++ b/libavdevice/decklink_common_c.h @@ -28,6 +28,7 @@ typedef enum DecklinkPtsSource { PTS_SRC_VIDEO = 2, PTS_SRC_REFERENCE = 3, PTS_SRC_WALLCLOCK = 4, +PTS_SRC_NB } DecklinkPtsSource; struct decklink_cctx { diff --git a/libavdevice/decklink_dec_c.c b/libavdevice/decklink_dec_c.c index 6fb5ffe..d52dde5 100644 --- a/libavdevice/decklink_dec_c.c +++ b/libavdevice/decklink_dec_c.c @@ -64,8 +64,8 @@ static const AVOption options[] = { { "analog_xlr",NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 4}, 0, 0,DEC, "audio_input"}, { "analog_rca",NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 5}, 0, 0,DEC, "audio_input"}, { "microphone",NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 6}, 0, 0,DEC, "audio_input"}, -{ "audio_pts", "audio pts source", OFFSET(audio_pts_source), AV_OPT_TYPE_INT, { .i64 = PTS_SRC_AUDIO}, 1, 4, DEC, "pts_source"}, -{ "video_pts", "video pts source", OFFSET(video_pts_source), AV_OPT_TYPE_INT, { .i64 = PTS_SRC_VIDEO}, 1, 4, DEC, "pts_source"}, +{ "audio_pts", "audio pts source", OFFSET(audio_pts_source), AV_OPT_TYPE_INT, { .i64 = PTS_SRC_AUDIO}, 1, PTS_SRC_NB-1, DEC, "pts_source"}, +{ "video_pts", "video pts source", OFFSET(video_pts_source), AV_OPT_TYPE_INT, { .i64 = PTS_SRC_VIDEO}, 1, PTS_SRC_NB-1, DEC, "pts_source"}, { "audio", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PTS_SRC_AUDIO}, 0, 0, DEC, "pts_source"}, { "video", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PTS_SRC_VIDEO}, 0, 0, DEC, "pts_source"}, { "reference", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PTS_SRC_REFERENCE}, 0, 0, DEC, "pts_source"}, -- 1.9.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH v2 1/3] avdevice/decklink: addition of copyts option
From: Vishwanath Dixit --- doc/indevs.texi | 5 + libavdevice/decklink_common_c.h | 1 + libavdevice/decklink_dec.cpp| 18 +++--- libavdevice/decklink_dec_c.c| 1 + 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/doc/indevs.texi b/doc/indevs.texi index 56066bf..36aef49 100644 --- a/doc/indevs.texi +++ b/doc/indevs.texi @@ -317,6 +317,11 @@ Defaults to @samp{1073741824}. Sets the audio sample bit depth. Must be @samp{16} or @samp{32}. Defaults to @samp{16}. +@item decklink_copyts +If set to @option{true}, timestamps are forwarded as they are without removing +the initial offset. +Defaults to @option{false}. + @end table @subsection Examples diff --git a/libavdevice/decklink_common_c.h b/libavdevice/decklink_common_c.h index 368ac25..ac6563a 100644 --- a/libavdevice/decklink_common_c.h +++ b/libavdevice/decklink_common_c.h @@ -52,6 +52,7 @@ struct decklink_cctx { char *format_code; int raw_format; int64_t queue_size; +int copyts; }; #endif /* AVDEVICE_DECKLINK_COMMON_C_H */ diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp index 94dae26..1fd40ca 100644 --- a/libavdevice/decklink_dec.cpp +++ b/libavdevice/decklink_dec.cpp @@ -586,7 +586,8 @@ static int64_t get_pkt_pts(IDeckLinkVideoInputFrame *videoFrame, IDeckLinkAudioInputPacket *audioFrame, int64_t wallclock, DecklinkPtsSource pts_src, - AVRational time_base, int64_t *initial_pts) + AVRational time_base, int64_t *initial_pts, + int copyts) { int64_t pts = AV_NOPTS_VALUE; BMDTimeValue bmd_pts; @@ -619,10 +620,12 @@ static int64_t get_pkt_pts(IDeckLinkVideoInputFrame *videoFrame, if (res == S_OK) pts = bmd_pts / time_base.num; -if (pts != AV_NOPTS_VALUE && *initial_pts == AV_NOPTS_VALUE) -*initial_pts = pts; -if (*initial_pts != AV_NOPTS_VALUE) -pts -= *initial_pts; +if (!copyts) { +if (pts != AV_NOPTS_VALUE && *initial_pts == AV_NOPTS_VALUE) +*initial_pts = pts; +if (*initial_pts != AV_NOPTS_VALUE) +pts -= *initial_pts; +} return pts; } @@ -635,6 +638,7 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( BMDTimeValue frameTime; BMDTimeValue frameDuration; int64_t wallclock = 0; +struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data; if (ctx->autodetect) { if (videoFrame && !(videoFrame->GetFlags() & bmdFrameHasNoInputSource) && @@ -694,7 +698,7 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( no_video = 0; } -pkt.pts = get_pkt_pts(videoFrame, audioFrame, wallclock, ctx->video_pts_source, ctx->video_st->time_base, &initial_video_pts); +pkt.pts = get_pkt_pts(videoFrame, audioFrame, wallclock, ctx->video_pts_source, ctx->video_st->time_base, &initial_video_pts, cctx->copyts); pkt.dts = pkt.pts; pkt.duration = frameDuration; @@ -785,7 +789,7 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( pkt.size = audioFrame->GetSampleFrameCount() * ctx->audio_st->codecpar->channels * (ctx->audio_depth / 8); audioFrame->GetBytes(&audioFrameBytes); audioFrame->GetPacketTime(&audio_pts, ctx->audio_st->time_base.den); -pkt.pts = get_pkt_pts(videoFrame, audioFrame, wallclock, ctx->audio_pts_source, ctx->audio_st->time_base, &initial_audio_pts); +pkt.pts = get_pkt_pts(videoFrame, audioFrame, wallclock, ctx->audio_pts_source, ctx->audio_st->time_base, &initial_audio_pts, cctx->copyts); pkt.dts = pkt.pts; //fprintf(stderr,"Audio Frame size %d ts %d\n", pkt.size, pkt.pts); diff --git a/libavdevice/decklink_dec_c.c b/libavdevice/decklink_dec_c.c index 1c6d826..6fb5ffe 100644 --- a/libavdevice/decklink_dec_c.c +++ b/libavdevice/decklink_dec_c.c @@ -73,6 +73,7 @@ static const AVOption options[] = { { "draw_bars", "draw bars on signal loss" , OFFSET(draw_bars), AV_OPT_TYPE_BOOL, { .i64 = 1}, 0, 1, DEC }, { "queue_size","input queue buffer size", OFFSET(queue_size), AV_OPT_TYPE_INT64, { .i64 = (1024 * 1024 * 1024)}, 0, INT64_MAX, DEC }, { "audio_depth", "audio bitdepth (16 or 32)", OFFSET(audio_depth), AV_OPT_TYPE_INT, { .i64 = 16}, 16, 32, DEC }, +{ "decklink_copyts", "copy timestamps, do not remove the initial offset", OFFSET(copyts), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, DEC }, { NULL }, }; -- 1.9.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH v2 3/3] avdevice/decklink: addition of absolute wallclock option for pts source
From: Vishwanath Dixit --- doc/indevs.texi | 6 -- libavdevice/decklink_common_c.h | 1 + libavdevice/decklink_dec.cpp| 4 libavdevice/decklink_dec_c.c| 1 + 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/doc/indevs.texi b/doc/indevs.texi index 36aef49..0bc8e6a 100644 --- a/doc/indevs.texi +++ b/doc/indevs.texi @@ -298,11 +298,13 @@ Sets the audio input source. Must be @samp{unset}, @samp{embedded}, @item video_pts Sets the video packet timestamp source. Must be @samp{video}, @samp{audio}, -@samp{reference} or @samp{wallclock}. Defaults to @samp{video}. +@samp{reference}, @samp{wallclock} or @samp{abs_wallclock}. +Defaults to @samp{video}. @item audio_pts Sets the audio packet timestamp source. Must be @samp{video}, @samp{audio}, -@samp{reference} or @samp{wallclock}. Defaults to @samp{audio}. +@samp{reference}, @samp{wallclock} or @samp{abs_wallclock}. +Defaults to @samp{audio}. @item draw_bars If set to @samp{true}, color bars are drawn in the event of a signal loss. diff --git a/libavdevice/decklink_common_c.h b/libavdevice/decklink_common_c.h index 18097e2..08e9f9b 100644 --- a/libavdevice/decklink_common_c.h +++ b/libavdevice/decklink_common_c.h @@ -28,6 +28,7 @@ typedef enum DecklinkPtsSource { PTS_SRC_VIDEO = 2, PTS_SRC_REFERENCE = 3, PTS_SRC_WALLCLOCK = 4, +PTS_SRC_ABS_WALLCLOCK = 5, PTS_SRC_NB } DecklinkPtsSource; diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp index 1fd40ca..c6eea43 100644 --- a/libavdevice/decklink_dec.cpp +++ b/libavdevice/decklink_dec.cpp @@ -607,6 +607,8 @@ static int64_t get_pkt_pts(IDeckLinkVideoInputFrame *videoFrame, res = videoFrame->GetHardwareReferenceTimestamp(time_base.den, &bmd_pts, &bmd_duration); break; case PTS_SRC_WALLCLOCK: +/* fall through */ +case PTS_SRC_ABS_WALLCLOCK: { /* MSVC does not support compound literals like AV_TIME_BASE_Q * in C++ code (compiler error C4576) */ @@ -652,6 +654,8 @@ HRESULT decklink_input_callback::VideoInputFrameArrived( ctx->frameCount++; if (ctx->audio_pts_source == PTS_SRC_WALLCLOCK || ctx->video_pts_source == PTS_SRC_WALLCLOCK) wallclock = av_gettime_relative(); +else if (ctx->audio_pts_source == PTS_SRC_ABS_WALLCLOCK || ctx->video_pts_source == PTS_SRC_ABS_WALLCLOCK) +wallclock = av_gettime(); // Handle Video Frame if (videoFrame) { diff --git a/libavdevice/decklink_dec_c.c b/libavdevice/decklink_dec_c.c index d52dde5..00fb3af 100644 --- a/libavdevice/decklink_dec_c.c +++ b/libavdevice/decklink_dec_c.c @@ -70,6 +70,7 @@ static const AVOption options[] = { { "video", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PTS_SRC_VIDEO}, 0, 0, DEC, "pts_source"}, { "reference", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PTS_SRC_REFERENCE}, 0, 0, DEC, "pts_source"}, { "wallclock", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PTS_SRC_WALLCLOCK}, 0, 0, DEC, "pts_source"}, +{ "abs_wallclock", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PTS_SRC_ABS_WALLCLOCK}, 0, 0, DEC, "pts_source"}, { "draw_bars", "draw bars on signal loss" , OFFSET(draw_bars), AV_OPT_TYPE_BOOL, { .i64 = 1}, 0, 1, DEC }, { "queue_size","input queue buffer size", OFFSET(queue_size), AV_OPT_TYPE_INT64, { .i64 = (1024 * 1024 * 1024)}, 0, INT64_MAX, DEC }, { "audio_depth", "audio bitdepth (16 or 32)", OFFSET(audio_depth), AV_OPT_TYPE_INT, { .i64 = 16}, 16, 32, DEC }, -- 1.9.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avfilter/vidstab: set bytesPerPixel only for packed formats.
On 1/4/2018 5:25 PM, Gyan Doshi wrote: On 12/29/2017 8:38 AM, Michael Niedermayer wrote: On Thu, Dec 28, 2017 at 12:50:00PM -0900, Lou Logan wrote: On Thu, Dec 28, 2017, at 11:51 AM, Michael Niedermayer wrote: who maintains vf_vidstabtransform.c ? Realistically, nobody. Ideally, should have been Georg Martius who is the original author of the filter and also of vid.stab itself. Consider CCing him at "martius at mis.mpg.de" or "georg.martius at web.de". ok, cc added Georg, do you want to maintain vf_vidstabtransform.c ? If not, who wants to maintain vf_vidstabtransform.c ? If noone then iam not sure who will test or apply this, i think many dont have the dependancy installed ... I assume the author hasn't gotten back yet. Can anyone else test and apply this? Anyone? ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 2/2] avdevice/decklink: addition of absolute wallclock option for pts source
On 1/9/18 3:22 AM, Moritz Barsnick wrote: > On Mon, Jan 08, 2018 at 10:56:56 +0530, vdi...@akamai.com wrote: > >> -{ "audio_pts", "audio pts source", OFFSET(audio_pts_source), >> AV_OPT_TYPE_INT, { .i64 = PTS_SRC_AUDIO}, 1, 4, DEC, "pts_source"}, >> -{ "video_pts", "video pts source", OFFSET(video_pts_source), >> AV_OPT_TYPE_INT, { .i64 = PTS_SRC_VIDEO}, 1, 4, DEC, "pts_source"}, >> +{ "audio_pts", "audio pts source", OFFSET(audio_pts_source), >> AV_OPT_TYPE_INT, { .i64 = PTS_SRC_AUDIO}, 1, 5, DEC, "pts_source"}, >> +{ "video_pts", "video pts source", OFFSET(video_pts_source), >> AV_OPT_TYPE_INT, { .i64 = PTS_SRC_VIDEO}, 1, 5, DEC, "pts_source"}, > > This cries for a max macro: > > PTS_SRC_VIDEO = 2, > PTS_SRC_REFERENCE = 3, > PTS_SRC_WALLCLOCK = 4, > +PTS_SRC_ABS_WALLCLOCK = 5, > +PTS_SRC_NB > } DecklinkPtsSource; > > and then > > +{ "audio_pts", "audio pts source", OFFSET(audio_pts_source), > AV_OPT_TYPE_INT, { .i64 = PTS_SRC_AUDIO}, 1, PTS_SRC_NB-1, DEC, > "pts_source"}, > +{ "video_pts", "video pts source", OFFSET(video_pts_source), > AV_OPT_TYPE_INT, { .i64 = PTS_SRC_VIDEO}, 1, PTS_SRC_NB-1, DEC, > "pts_source"}, > >> break; >> case PTS_SRC_WALLCLOCK: >> +case PTS_SRC_ABS_WALLCLOCK: > > Coverty and similar tools like fall-throughs to be marked as such to > avoid false warnings. > >> +else if(ctx->audio_pts_source == PTS_SRC_ABS_WALLCLOCK || >> ctx->video_pts_source == PTS_SRC_ABS_WALLCLOCK) > > "else if (" > > Moritz > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel Thanks for your review comments. I have made the suggested changes and have submitted the revised patch set with version v2. https://patchwork.ffmpeg.org/patch/7243/, https://patchwork.ffmpeg.org/patch/7242/, https://patchwork.ffmpeg.org/patch/7244/ ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] configure: don't use SDL.h in check_func_headers when checking for SDL2
On 1/7/2018 6:15 PM, James Almer wrote: > check_func_headers() defines a main() function, which clashes with a > redefinition done by said SDL header. Check for SDL_PollEvent using > SDL_events.h only instead, where the redefinition doesn't happen. > > Fixes a regression since d03c39b46b21c893d6549a532289b7fb9935b3fc. > > Tested-by: RiCON > Signed-off-by: James Almer > --- > configure | 8 +++- > 1 file changed, 3 insertions(+), 5 deletions(-) > > diff --git a/configure b/configure > index ab05b9c7f3..1aea18d300 100755 > --- a/configure > +++ b/configure > @@ -6008,15 +6008,13 @@ fi > > if enabled sdl2; then > SDL2_CONFIG="${cross_prefix}sdl2-config" > -if test_pkg_config sdl2 "sdl2 >= 2.0.1 sdl2 < 2.1.0" SDL_events.h > SDL_PollEvent; then > -check_func_headers SDL.h SDL_Init $sdl2_extralibs $sdl2_cflags || > -disable sdl2 > -elif "${SDL2_CONFIG}" --version > /dev/null 2>&1; then > +test_pkg_config sdl2 "sdl2 >= 2.0.1 sdl2 < 2.1.0" SDL_events.h > SDL_PollEvent > +if disabled sdl2 && "${SDL2_CONFIG}" --version > /dev/null 2>&1; then > sdl2_cflags=$("${SDL2_CONFIG}" --cflags) > sdl2_extralibs=$("${SDL2_CONFIG}" --libs) > check_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | > SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) >= 0x020001" $sdl2_cflags && > check_cpp_condition SDL.h "(SDL_MAJOR_VERSION<<16 | > SDL_MINOR_VERSION<<8 | SDL_PATCHLEVEL) < 0x020100" $sdl2_cflags && > -check_func_headers SDL.h SDL_Init $sdl2_extralibs $sdl2_cflags && > +check_func_headers SDL_events.h SDL_PollEvent $sdl2_extralibs > $sdl2_cflags && > enable sdl2 > fi > if test $target_os = "mingw32"; then Will push this soon. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avformat/aiffdec: AIFF fix in case of ANNO
Yes, the problem found from playing the file AIFF file you can download it from: https://www.datafilehost.com/d/60337fcd On Tue, Jan 9, 2018 at 10:53 PM, Michael Niedermayer wrote: > On Mon, Jan 08, 2018 at 02:03:40PM +, endus...@gmail.com wrote: > > From: Eduard Sinelnikov > > > > Apple's AIFF protocol clearly states that each chucnk which is odd sized > a padding should be added. > > In the old version of aiffdec adding of padding was done in `get_meta`. > And in case of unknown chunk name it was done in defalut case. > > The new version has deleted the padding in default case and added > padding adding after the switch. > > But the new version didn't removed the padding adding in the `get_meta` > function so in some cases padding was added twice which leaded to a bug. > > do you have a testcase you can share that shows the probnlem ? > or did you find the issue thorugh code review ? > > [...] > -- > Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB > > It is dangerous to be right in matters on which the established authorities > are wrong. -- Voltaire > > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] add dumpwave filter
Hi, On Tue, Jan 9, 2018 at 3:49 PM, wrote: > From: Dmytro Humeniuk > > Signed-off-by: Dmytro Humeniuk > --- > Changelog | 1 + > doc/filters.texi | 23 > libavfilter/Makefile | 1 + > libavfilter/af_dumpwave.c | 285 + > libavfilter/allfilters.c | 1 + > libavfilter/version.h | 4 +- > tests/fate/filter-audio.mak| 5 + > tests/ref/fate/filter-dumpwave | 1 + > 8 files changed, 319 insertions(+), 2 deletions(-) > create mode 100644 libavfilter/af_dumpwave.c > create mode 100644 tests/ref/fate/filter-dumpwave I could see this possibly being a useful filter, but I'm confused about where the JSON schema came from. The two JS libraries that do this type of thing (waveform.js, and wavesurer.js) both just load waveform data as an array of floats. If we're going to add something like this to libavfilter it should be as generic and extensible as possible. I'm not wild about the string stuff, and the big sample format switch isn't necessary. I could do a code review, but it might just be faster if I rewrite it and send another patch. Is that OK with you? Thanks, Kyle ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] add dumpwave filter
There is no rush on this. Could you please do a code review so I can see how to do things properly? > On 10 Jan 2018, at 08:43, Kyle Swanson wrote: > > Hi, > > On Tue, Jan 9, 2018 at 3:49 PM, wrote: >> From: Dmytro Humeniuk >> >> Signed-off-by: Dmytro Humeniuk >> --- >> Changelog | 1 + >> doc/filters.texi | 23 >> libavfilter/Makefile | 1 + >> libavfilter/af_dumpwave.c | 285 > + >> libavfilter/allfilters.c | 1 + >> libavfilter/version.h | 4 +- >> tests/fate/filter-audio.mak| 5 + >> tests/ref/fate/filter-dumpwave | 1 + >> 8 files changed, 319 insertions(+), 2 deletions(-) >> create mode 100644 libavfilter/af_dumpwave.c >> create mode 100644 tests/ref/fate/filter-dumpwave > > I could see this possibly being a useful filter, but I'm confused about > where the JSON schema came from. The two JS libraries that do this type of > thing (waveform.js, and wavesurer.js) both just load waveform data as an > array of floats. If we're going to add something like this to libavfilter > it should be as generic and extensible as possible. I'm not wild about the > string stuff, and the big sample format switch isn't necessary. I could do > a code review, but it might just be faster if I rewrite it and send another > patch. Is that OK with you? > > Thanks, > Kyle > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel smime.p7s Description: S/MIME cryptographic signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] avfilter: add dumpwave filter.
From: Dmytro Humeniuk Signed-off-by: Dmytro Humeniuk --- Changelog | 1 + doc/filters.texi | 23 libavfilter/Makefile | 1 + libavfilter/af_dumpwave.c | 285 + libavfilter/allfilters.c | 1 + libavfilter/version.h | 4 +- tests/fate/filter-audio.mak| 5 + tests/ref/fate/filter-dumpwave | 1 + 8 files changed, 319 insertions(+), 2 deletions(-) create mode 100644 libavfilter/af_dumpwave.c create mode 100644 tests/ref/fate/filter-dumpwave diff --git a/Changelog b/Changelog index 61075b3392..40fd624449 100644 --- a/Changelog +++ b/Changelog @@ -38,6 +38,7 @@ version : - Removed the ffserver program - Removed the ffmenc and ffmdec muxer and demuxer - VideoToolbox HEVC encoder and hwaccel +- dumpwave audio filter version 3.4: diff --git a/doc/filters.texi b/doc/filters.texi index d29c40080f..98e54aec6e 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -2529,6 +2529,29 @@ Optional. It should have a value much less than 1 (e.g. 0.05 or 0.02) and is used to prevent clipping. @end table +@section dumpwave +Dumps RMS amplitude to JSON file. +Converts samples to decibels and calculates RMS (Root-Mean-Square) audio power scaled to desired values. + +@table @option +@item d +Dimensions @code{WxH}. +@code{W} - number of data values in json, values will be scaled according to @code{H}. +The default value is @var{640x480} + +@item s +Samples count per value per channel + +@item json +Path to json file +@end table + +For example, to generate RMS amplitude for 44.1 kHz 6 seconds length audio +with dimensions @var{1800x140}, samples count @code{44100*6/1800=147} and store it to @var{/tmp/out.json}, you might use: +@example +dumpwave=d=1800x140:s=147:json=/tmp/out.json +@end example + @section dynaudnorm Dynamic Audio Normalizer. diff --git a/libavfilter/Makefile b/libavfilter/Makefile index ef4729dd3f..2ffbc9497a 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -87,6 +87,7 @@ OBJS-$(CONFIG_COMPENSATIONDELAY_FILTER) += af_compensationdelay.o OBJS-$(CONFIG_CROSSFEED_FILTER) += af_crossfeed.o OBJS-$(CONFIG_CRYSTALIZER_FILTER)+= af_crystalizer.o OBJS-$(CONFIG_DCSHIFT_FILTER)+= af_dcshift.o +OBJS-$(CONFIG_DUMPWAVE_FILTER) += af_dumpwave.o OBJS-$(CONFIG_DYNAUDNORM_FILTER) += af_dynaudnorm.o OBJS-$(CONFIG_EARWAX_FILTER) += af_earwax.o OBJS-$(CONFIG_EBUR128_FILTER)+= f_ebur128.o diff --git a/libavfilter/af_dumpwave.c b/libavfilter/af_dumpwave.c new file mode 100644 index 00..35b970af6c --- /dev/null +++ b/libavfilter/af_dumpwave.c @@ -0,0 +1,285 @@ +/* + * Copyright (c) 2017 Dmytro Humeniuk + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * waveform audio filter – dumps RMS amplitude to JSON file + */ + +#include "libavutil/avassert.h" +#include "libavutil/avstring.h" +#include "libavutil/channel_layout.h" +#include "libavutil/opt.h" +#include "libavutil/parseutils.h" +#include "avfilter.h" +#include "formats.h" +#include "audio.h" +#include "internal.h" + +typedef struct DumpWaveContext { +const AVClass *class; /**< class for AVOptions */ +int w; /**< number of data values in json */ +int h; /**< values will be scaled according to provided */ +int is_disabled;/**< disable filter in case it's misconfigured */ +int i; /**< index of value */ +char *json; /**< path to json */ +char *str; /**< comma separated values */ +double *values; /**< scaling factors */ +int64_t s; /**< samples per value per channel */ +int64_t n; /**< current number of samples counted */ +int64_t max_samples;/**< samples per value */ +double sum; /**< sum of the squared samples per value */ +} DumpWaveContext; + +#define OFFSET(x) offsetof(DumpWaveContext, x) +#define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM + +static const AVOption dumpwave_options[] = { +{ "d", "set width and height", OFFSET(w), AV_OPT_TYPE_IMAGE_SIZE, {.str = "640x480"