Re: [FFmpeg-devel] [PATCH] display: Add AVDisplayOrientation API
On Wed, Apr 4, 2018 at 8:30 AM, Vittorio Giovara wrote: > The transformation operations that can be described by a display matrix > are not limited to pure rotation, but include horizontal and vertical > flip, as well as transpose and antitranspose. Unfortunately the current > API can only return a rotation angle in degrees, and is not designed to > detect flip operations or a combination of rotation and flip. > > So implement an additional API to analyze the display matrix and return > the most common rotation operations (multiples of 90º) as well flips or > a combination thereof. This function returns a bitfield mask composed of > AVDisplayOrientation elements that describe which rendering operations > should be performed on the frame. The existing API is still available > and useful in case of custom rotations. > > Signed-off-by: Vittorio Giovara > --- > Note: the new operations describe a clockwise rotation, while the > old API provided a counterclockwise rotation. I always felt this was > a mistake as it's counterintuitive and suprising to new users, so I > didn't want to cargo-cult it to a new API. What do people think about it? > i am more used to counter-clockwise angle representation just like zero-indexing, but either way is fine with me. > See also https://github.com/FFMS/ffms2/issues/317 for flipped samples, > code, > and additional discussion. > > Missing changelog entry and version bump. > Vittorio > > libavutil/display.c | 92 ++ > +++ > libavutil/display.h | 53 ++ > 2 files changed, 145 insertions(+) > > diff --git a/libavutil/display.c b/libavutil/display.c > index f7500948ff..839961ec20 100644 > --- a/libavutil/display.c > +++ b/libavutil/display.c > @@ -22,6 +22,7 @@ > #include > #include > > +#include "avstring.h" > #include "display.h" > #include "mathematics.h" > > @@ -73,3 +74,94 @@ void av_display_matrix_flip(int32_t matrix[9], int > hflip, int vflip) > for (i = 0; i < 9; i++) > matrix[i] *= flip[i % 3]; > } > + > +uint32_t av_display_orientation_get(int32_t matrix_src[9]) > +{ > +int32_t matrix[9]; > +uint32_t orientation = 0; > +int64_t det = (int64_t)matrix_src[0] * matrix_src[4] - > (int64_t)matrix_src[1] * matrix_src[3]; > + > +/* Duplicate matrix so that the input one is not modified in case of > flip. */ > +memcpy(matrix, matrix_src, sizeof(*matrix_src) * 9); > + > +if (det < 0) { > +/* Always assume an horizontal flip for simplicity, it can be > + * changed later if rotation is 180º. */ > +orientation = AV_FLIP_HORIZONTAL; > +av_display_matrix_flip(matrix, 1, 0); > +} > + > +if (matrix[1] == (1 << 16) && matrix[3] == -(1 << 16)) { > +orientation |= AV_ROTATION_90; > +} else if (matrix[0] == -(1 << 16) && matrix[4] == -(1 << 16)) { > +if (det < 0) > +orientation = AV_FLIP_VERTICAL; > +else > +orientation |= AV_ROTATION_180; > +} else if (matrix[1] == -(1 << 16) && matrix[3] == (1 << 16)) { > +orientation |= AV_ROTATION_270; > +} else if (matrix[0] == (1 << 16) && matrix[4] == (1 << 16)) { > +orientation |= AV_IDENTITY; > +} else { > +orientation |= AV_ROTATION_CUSTOM; > +} > + > +return orientation; > +} > + > +void av_display_orientation_set(int32_t matrix[9], uint32_t orientation, > double angle) > +{ > +int hflip = !!(orientation & AV_FLIP_HORIZONTAL); > +int vflip = !!(orientation & AV_FLIP_VERTICAL); > + > +memset(matrix, 0, sizeof(*matrix) * 9); > +matrix[8] = 1 << 30; > + > +if (orientation & AV_IDENTITY) { > +matrix[0] = 1 << 16; > +matrix[4] = 1 << 16; > +} else if (orientation & AV_ROTATION_90) { > +matrix[1] = 1 << 16; > +matrix[3] = -(1 << 16); > +} else if (orientation & AV_ROTATION_180) { > +matrix[0] = -(1 << 16); > +matrix[4] = -(1 << 16); > +} else if (orientation & AV_ROTATION_270) { > +matrix[1] = -(1 << 16); > +matrix[3] = 1 << 16; > +} else if (orientation & AV_ROTATION_CUSTOM) { > +av_display_rotation_set(matrix, angle); > +} > + > +av_display_matrix_flip(matrix, hflip, vflip); > +} > + > +void av_display_orientation_name(uint32_t orientation, char *buf, size_t > buf_size) > +{ > +if (orientation == 0) { > +av_strlcpy(buf, "identity", buf_size); > +return; > +} > + > +if (orientation & AV_ROTATION_90) > +av_strlcpy(buf, "rotation_90", buf_size); > +else if (orientation & AV_ROTATION_180) > +av_strlcpy(buf, "rotation_180", buf_size); > +else if (orientation & AV_ROTATION_270) > +av_strlcpy(buf, "rotation_270", buf_size); > +else if (orientation & AV_ROTATION_CUSTOM) > +av_strlcpy(buf, "rotation_custom", buf_size); > +else > +buf[0] = '\0'; > + > +if (orientation & AV_FLIP_HORIZONTAL) { >
Re: [FFmpeg-devel] [PATCH 2/3] avformat/vivo: improve probing of some files
On Wed, Apr 04, 2018 at 10:40:39PM +0200, Paul B Mahol wrote: > On 4/4/18, Michael Niedermayer wrote: > > On Wed, Apr 04, 2018 at 04:09:36PM +0200, Paul B Mahol wrote: > >> Signed-off-by: Paul B Mahol > >> --- > >> libavformat/vivo.c | 5 +++-- > >> 1 file changed, 3 insertions(+), 2 deletions(-) > >> > >> diff --git a/libavformat/vivo.c b/libavformat/vivo.c > >> index c9e9c37f37..6a88a09a01 100644 > >> --- a/libavformat/vivo.c > >> +++ b/libavformat/vivo.c > >> @@ -59,9 +59,10 @@ static int vivo_probe(AVProbeData *p) > >> if (c & 0x80 || length > 1024 || length < 21) > >> return 0; > >> > >> -if (memcmp(buf, "\r\nVersion:Vivo/", 15)) > >> +buf += 2; > >> +if (memcmp(buf, "Version:Vivo/", 13)) > >> return 0; > > > > what is in the 2 bytes that are not checked anymore ? > > Irrelevant bytes. of course, but i was just wondering if this would not be more robust to skip "n" bytes of whitespace. That is unless you know it will always be 2 or there are cases where its not whitespace [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB "You are 36 times more likely to die in a bathtub than at the hands of a terrorist. Also, you are 2.5 times more likely to become a president and 2 times more likely to become an astronaut, than to die in a terrorist attack." -- Thoughty2 signature.asc Description: PGP signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/3] avformat/matroskadec: use refcounted buffers in EbmlBin
Data in EbmlBin objects is never changed after being read from the input file (save for two specific cases with encoded CodePrivate), so using AVBufferRef we can prevent unnecessary copy of data by instead creating new references to said constant data. Signed-off-by: James Almer --- The CodecPrivate parts are untested, as there's no FATE coverage of them. libavformat/matroskadec.c | 44 +++- 1 file changed, 31 insertions(+), 13 deletions(-) diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 6156c2f9b4..029929a1cb 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -104,6 +104,7 @@ typedef struct EbmlList { typedef struct EbmlBin { int size; +AVBufferRef *buf; uint8_t *data; int64_t pos; } EbmlBin; @@ -962,14 +963,19 @@ static int ebml_read_ascii(AVIOContext *pb, int size, char **str) */ static int ebml_read_binary(AVIOContext *pb, int length, EbmlBin *bin) { -av_fast_padded_malloc(&bin->data, &bin->size, length); -if (!bin->data) -return AVERROR(ENOMEM); +int ret; +ret = av_buffer_realloc(&bin->buf, length + AV_INPUT_BUFFER_PADDING_SIZE); +if (ret < 0) +return ret; +memset(bin->buf->data + length, 0, AV_INPUT_BUFFER_PADDING_SIZE); + +bin->data = bin->buf->data; bin->size = length; bin->pos = avio_tell(pb); if (avio_read(pb, bin->data, length) != length) { -av_freep(&bin->data); +av_buffer_unref(&bin->buf); +bin->data = NULL; bin->size = 0; return AVERROR(EIO); } @@ -1252,7 +1258,7 @@ static void ebml_free(EbmlSyntax *syntax, void *data) av_freep(data_off); break; case EBML_BIN: -av_freep(&((EbmlBin *) data_off)->data); +av_buffer_unref(&((EbmlBin *) data_off)->buf); break; case EBML_LEVEL1: case EBML_NEST: @@ -2036,12 +2042,13 @@ static int get_qt_codec(MatroskaTrack *track, uint32_t *fourcc, enum AVCodecID * * by expanding/shifting the data by 4 bytes and storing the data * size at the start. */ if (ff_codec_get_id(codec_tags, AV_RL32(track->codec_priv.data))) { -uint8_t *p = av_realloc(track->codec_priv.data, -track->codec_priv.size + 4); -if (!p) -return AVERROR(ENOMEM); -memmove(p + 4, p, track->codec_priv.size); -track->codec_priv.data = p; +int ret = av_buffer_realloc(&track->codec_priv.buf, +track->codec_priv.size + 4 + AV_INPUT_BUFFER_PADDING_SIZE); +if (ret < 0) +return ret; + +track->codec_priv.data = track->codec_priv.buf->data; +memmove(track->codec_priv.data + 4, track->codec_priv.data, track->codec_priv.size); track->codec_priv.size += 4; AV_WB32(track->codec_priv.data, track->codec_priv.size); } @@ -2162,8 +2169,19 @@ static int matroska_parse_tracks(AVFormatContext *s) "Failed to decode codec private data\n"); } -if (codec_priv != track->codec_priv.data) -av_free(codec_priv); +if (codec_priv != track->codec_priv.data) { +av_buffer_unref(&track->codec_priv.buf); +if (track->codec_priv.data) { +track->codec_priv.buf = av_buffer_create(track->codec_priv.data, + track->codec_priv.size + AV_INPUT_BUFFER_PADDING_SIZE, + NULL, NULL, 0); +if (!track->codec_priv.buf) { +av_freep(&track->codec_priv.data); +track->codec_priv.size = 0; +return AVERROR(ENOMEM); +} +} +} } } -- 2.16.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 3/3] avformat/matroskadec: reference the existing data buffer when creating packets
Newly allocated data buffers (wavpack, prores, compressed buffers) are padded to meet the requirements of AVPacket. matroska_parse_frame() speed up is ~10x. Signed-off-by: James Almer --- libavformat/matroskadec.c | 45 +++-- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index e74db4ff1b..a6c095199f 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -1367,7 +1367,7 @@ static int matroska_decode_buffer(uint8_t **buf, int *buf_size, return 0; pkt_size = isize + header_size; -pkt_data = av_malloc(pkt_size); +pkt_data = av_malloc(pkt_size + AV_INPUT_BUFFER_PADDING_SIZE); if (!pkt_data) return AVERROR(ENOMEM); @@ -1379,7 +1379,8 @@ static int matroska_decode_buffer(uint8_t **buf, int *buf_size, case MATROSKA_TRACK_ENCODING_COMP_LZO: do { olen = pkt_size *= 3; -newpktdata = av_realloc(pkt_data, pkt_size + AV_LZO_OUTPUT_PADDING); +newpktdata = av_realloc(pkt_data, pkt_size + AV_LZO_OUTPUT_PADDING + + AV_INPUT_BUFFER_PADDING_SIZE); if (!newpktdata) { result = AVERROR(ENOMEM); goto failed; @@ -1404,7 +1405,7 @@ static int matroska_decode_buffer(uint8_t **buf, int *buf_size, zstream.avail_in = isize; do { pkt_size *= 3; -newpktdata = av_realloc(pkt_data, pkt_size); +newpktdata = av_realloc(pkt_data, pkt_size + AV_INPUT_BUFFER_PADDING_SIZE); if (!newpktdata) { inflateEnd(&zstream); result = AVERROR(ENOMEM); @@ -1437,7 +1438,7 @@ static int matroska_decode_buffer(uint8_t **buf, int *buf_size, bzstream.avail_in = isize; do { pkt_size *= 3; -newpktdata = av_realloc(pkt_data, pkt_size); +newpktdata = av_realloc(pkt_data, pkt_size + AV_INPUT_BUFFER_PADDING_SIZE); if (!newpktdata) { BZ2_bzDecompressEnd(&bzstream); result = AVERROR(ENOMEM); @@ -1464,6 +1465,8 @@ static int matroska_decode_buffer(uint8_t **buf, int *buf_size, return AVERROR_INVALIDDATA; } +memset(pkt_data + pkt_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); + *buf = pkt_data; *buf_size = pkt_size; return 0; @@ -3001,7 +3004,7 @@ static int matroska_parse_wavpack(MatroskaTrack *track, uint8_t *src, goto fail; } -tmp = av_realloc(dst, dstlen + blocksize + 32); +tmp = av_realloc(dst, dstlen + blocksize + 32 + AV_INPUT_BUFFER_PADDING_SIZE); if (!tmp) { ret = AVERROR(ENOMEM); goto fail; @@ -3025,6 +3028,8 @@ static int matroska_parse_wavpack(MatroskaTrack *track, uint8_t *src, offset += blocksize + 32; } +memset(dst + dstlen, 0, AV_INPUT_BUFFER_PADDING_SIZE); + *pdst = dst; *size = dstlen; @@ -3042,13 +3047,14 @@ static int matroska_parse_prores(MatroskaTrack *track, uint8_t *src, int dstlen = *size; if (AV_RB32(&src[4]) != MKBETAG('i', 'c', 'p', 'f')) { -uint8_t *dst = av_malloc(dstlen + 8); +uint8_t *dst = av_malloc(dstlen + 8 + AV_INPUT_BUFFER_PADDING_SIZE); if (!dst) return AVERROR(ENOMEM); AV_WB32(dst, dstlen); AV_WB32(dst + 4, MKBETAG('i', 'c', 'p', 'f')); memcpy(dst + 8, src, dstlen); +memset(dst + 8 + dstlen, 0, AV_INPUT_BUFFER_PADDING_SIZE); dstlen += 8; } @@ -3175,7 +3181,7 @@ static int matroska_parse_webvtt(MatroskaDemuxContext *matroska, static int matroska_parse_frame(MatroskaDemuxContext *matroska, MatroskaTrack *track, AVStream *st, -uint8_t *data, int pkt_size, +AVBufferRef *buf, uint8_t *data, int pkt_size, uint64_t timecode, uint64_t lace_duration, int64_t pos, int is_keyframe, uint8_t *additional, uint64_t additional_id, int additional_size, @@ -3218,17 +3224,20 @@ static int matroska_parse_frame(MatroskaDemuxContext *matroska, pkt_data = pr_data; } -/* XXX: prevent data copy... */ -if (av_new_packet(pkt, pkt_size) < 0) { +av_init_packet(pkt); +if (pkt_data != data) +pkt->buf = av_buffer_create(pkt_data, pkt_size + AV_INPUT_BUFFER_PADDING_SIZE, +NULL, NULL, 0); +else +pkt->buf = av_buffer_ref(buf); + +if (!pkt->buf) { res = AVERROR(ENOMEM); goto fail; } -memcpy(pkt->data, pkt_data, pkt_size); - -if (pkt_data != data) -av_freep(&pkt_data); - +pkt->data = pkt_data; +pkt->size = pkt_siz
[FFmpeg-devel] [PATCH 2/3] avformat/matroskadec: factor the prores packet parsing code out
Simplifies code in matroska_parse_frame(). This is in preparation for the following patch. Signed-off-by: James Almer --- Prores specific stuff untested, as FATE doesn't cover it. libavformat/matroskadec.c | 50 +++ 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 029929a1cb..e74db4ff1b 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -3035,6 +3035,29 @@ fail: return ret; } +static int matroska_parse_prores(MatroskaTrack *track, uint8_t *src, + uint8_t **pdst, int *size) +{ +uint8_t *dst = src; +int dstlen = *size; + +if (AV_RB32(&src[4]) != MKBETAG('i', 'c', 'p', 'f')) { +uint8_t *dst = av_malloc(dstlen + 8); +if (!dst) +return AVERROR(ENOMEM); + +AV_WB32(dst, dstlen); +AV_WB32(dst + 4, MKBETAG('i', 'c', 'p', 'f')); +memcpy(dst + 8, src, dstlen); +dstlen += 8; +} + +*pdst = dst; +*size = dstlen; + +return 0; +} + static int matroska_parse_webvtt(MatroskaDemuxContext *matroska, MatroskaTrack *track, AVStream *st, @@ -3160,7 +3183,7 @@ static int matroska_parse_frame(MatroskaDemuxContext *matroska, { MatroskaTrackEncoding *encodings = track->encodings.elem; uint8_t *pkt_data = data; -int offset = 0, res; +int res; AVPacket pktl, *pkt = &pktl; if (encodings && !encodings->type && encodings->scope & 1) { @@ -3182,23 +3205,26 @@ static int matroska_parse_frame(MatroskaDemuxContext *matroska, pkt_data = wv_data; } -if (st->codecpar->codec_id == AV_CODEC_ID_PRORES && -AV_RB32(&data[4]) != MKBETAG('i', 'c', 'p', 'f')) -offset = 8; +if (st->codecpar->codec_id == AV_CODEC_ID_PRORES) { +uint8_t *pr_data; +res = matroska_parse_prores(track, pkt_data, &pr_data, &pkt_size); +if (res < 0) { +av_log(matroska->ctx, AV_LOG_ERROR, + "Error parsing a prores block.\n"); +goto fail; +} +if (pkt_data != data) +av_freep(&pkt_data); +pkt_data = pr_data; +} /* XXX: prevent data copy... */ -if (av_new_packet(pkt, pkt_size + offset) < 0) { +if (av_new_packet(pkt, pkt_size) < 0) { res = AVERROR(ENOMEM); goto fail; } -if (st->codecpar->codec_id == AV_CODEC_ID_PRORES && offset == 8) { -uint8_t *buf = pkt->data; -bytestream_put_be32(&buf, pkt_size); -bytestream_put_be32(&buf, MKBETAG('i', 'c', 'p', 'f')); -} - -memcpy(pkt->data + offset, pkt_data, pkt_size); +memcpy(pkt->data, pkt_data, pkt_size); if (pkt_data != data) av_freep(&pkt_data); -- 2.16.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] libavformat/aac: Parse all ID3 tags present between ADTS frames
On 2018-04-04 09:22, Mattias Amnefelt wrote: On 2018-04-04 03:42, James Almer wrote: On 4/3/2018 10:40 PM, Carl Eugen Hoyos wrote: 2018-04-04 3:38 GMT+02:00, James Almer : On 4/3/2018 10:33 PM, Carl Eugen Hoyos wrote: The "-f aac" looks like a bad idea to me. It's also true for the tests above, but that's still not reason to add more. Please avoid top-posting here, Carl Eugen At least in one of them it was added because the sample had too few frames and probing was detecting it with a score of 1, which seemed too fragile. I believe that it is good to have a sample that is detected with a small score as part of fate. Carl Eugen When i asked it was suggested to just force the demuxer. I have no opinion one way or another, so feel free to change it. I have to admit I just copy-n-pasted the test above. I just double-checked and all the id3 tag tests pass without -f aac now. I'm not sure if anything has changed since the test was added or not. Do you want a patch which removes it for all of them? Here's an updated version of the patch without -f aac /mattiasa From 1d5ab8e48502c570b562ef4fdb6cf674f1d91e93 Mon Sep 17 00:00:00 2001 From: Mattias Amnefelt Date: Mon, 2 Apr 2018 11:30:40 +0200 Subject: [PATCH] libavformat/aac: Parse all ID3 tags present between ADTS frames Some ADTS streams can have multiple ID3 tags between frames. This change parses all of them, rather than just the first one. Signed-off-by: Mattias Amnefelt --- libavformat/aacdec.c | 14 +- tests/fate/demux.mak | 3 +- tests/ref/fate/adts-id3v2-two-tags-demux | 475 +++ 3 files changed, 486 insertions(+), 6 deletions(-) create mode 100644 tests/ref/fate/adts-id3v2-two-tags-demux diff --git a/libavformat/aacdec.c b/libavformat/aacdec.c index 5ec706bdc7..685458b911 100644 --- a/libavformat/aacdec.c +++ b/libavformat/aacdec.c @@ -154,11 +154,15 @@ static int adts_aac_read_packet(AVFormatContext *s, AVPacket *pkt) { int ret, fsize; -ret = av_get_packet(s->pb, pkt, FFMAX(ID3v2_HEADER_SIZE, ADTS_HEADER_SIZE)); - -if (ret >= ID3v2_HEADER_SIZE && ff_id3v2_match(pkt->data, ID3v2_DEFAULT_MAGIC)) { -if ((ret = handle_id3(s, pkt)) >= 0) -ret = av_get_packet(s->pb, pkt, ADTS_HEADER_SIZE); +// Parse all the ID3 headers between frames +while (1) { +ret = av_get_packet(s->pb, pkt, FFMAX(ID3v2_HEADER_SIZE, ADTS_HEADER_SIZE)); +if (ret >= ID3v2_HEADER_SIZE && ff_id3v2_match(pkt->data, ID3v2_DEFAULT_MAGIC)) { +if ((ret = handle_id3(s, pkt)) >= 0) { +continue; +} +} +break; } if (ret < 0) diff --git a/tests/fate/demux.mak b/tests/fate/demux.mak index 306904b9de..ef9e677821 100644 --- a/tests/fate/demux.mak +++ b/tests/fate/demux.mak @@ -1,10 +1,11 @@ FATE_SAMPLES_DEMUX-$(call DEMDEC, AVI, FRAPS) += fate-avio-direct fate-avio-direct: CMD = framecrc -avioflags direct -i $(TARGET_SAMPLES)/fraps/fraps-v5-bouncing-balls-partial.avi -avioflags direct -FATE_SAMPLES_DEMUX-$(call DEMDEC, AAC, AAC) += fate-adts-demux fate-adts-id3v1-demux fate-adts-id3v2-demux +FATE_SAMPLES_DEMUX-$(call DEMDEC, AAC, AAC) += fate-adts-demux fate-adts-id3v1-demux fate-adts-id3v2-demux fate-adts-id3v2-two-tags-demux fate-adts-demux: CMD = crc -i $(TARGET_SAMPLES)/aac/ct_faac-adts.aac -c:a copy fate-adts-id3v1-demux: CMD = framecrc -f aac -i $(TARGET_SAMPLES)/aac/id3v1.aac -c:a copy fate-adts-id3v2-demux: CMD = framecrc -f aac -i $(TARGET_SAMPLES)/aac/id3v2.aac -c:a copy +fate-adts-id3v2-two-tags-demux: CMD = framecrc -i $(TARGET_SAMPLES)/aac/id3v2_two_tags.aac -c:a copy FATE_SAMPLES_DEMUX-$(CONFIG_AEA_DEMUXER) += fate-aea-demux fate-aea-demux: CMD = crc -i $(TARGET_SAMPLES)/aea/chirp.aea -c:a copy diff --git a/tests/ref/fate/adts-id3v2-two-tags-demux b/tests/ref/fate/adts-id3v2-two-tags-demux new file mode 100644 index 00..4fffd2e767 --- /dev/null +++ b/tests/ref/fate/adts-id3v2-two-tags-demux @@ -0,0 +1,475 @@ +#tb 0: 1/28224000 +#media_type 0: audio +#codec_id 0: aac +#sample_rate 0: 48000 +#channel_layout 0: 4 +#channel_layout_name 0: mono +0, 0, 0, 602112, 128, 0x23291993 +0, 602112, 602112, 602112, 128, 0x23291993 +0,1204224,1204224, 602112, 128, 0x23291993 +0,1806336,1806336, 602112, 128, 0x23291993 +0,2408448,2408448, 602112, 128, 0x23291993 +0,3010560,3010560, 602112, 128, 0x23291993 +0,3612672,3612672, 602112, 128, 0x23291993 +0,4214784,4214784, 602112, 128, 0x23291993 +0,4816896,4816896, 602112, 128, 0x23291993 +0,5419008,5419008, 602112, 128, 0x23291993 +0,6021120,6021120, 602112, 128, 0x23291993 +0,6623232,6623232, 602112, 128, 0x23291993 +0,7225344,7225344, 602112, 128, 0x23291993 +0,7827456,7827456, 602112, 128,
[FFmpeg-devel] [PATCH]lavf/amr: Stricter heuristic for auto-detection.
Hi! Attached patch fixes ticket #7125, the jpg file in question contains a repeated pattern up to PROBE_SIZE that plays as amr_nb: 000d3290 05 14 51 40 05 14 51 40 05 14 51 40 05 14 51 40 |..Q@..Q@..Q@..Q@| * 00112900 1f ff d9 |...| Please comment, Carl Eugen From 26712381d7dc3d3dfc623a77a80a697ffcd54124 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Thu, 5 Apr 2018 00:41:55 +0200 Subject: [PATCH] lavf/amr: Stricter heuristic for auto-detection. Fixes ticket #7125. --- libavformat/amr.c | 10 ++ 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/libavformat/amr.c b/libavformat/amr.c index 8b4d736..f954803 100644 --- a/libavformat/amr.c +++ b/libavformat/amr.c @@ -178,7 +178,7 @@ AVInputFormat ff_amr_demuxer = { #if CONFIG_AMRNB_DEMUXER static int amrnb_probe(AVProbeData *p) { -int mode, i = 0, valid = 0; +int mode, i = 0, valid = 0, invalid = 0; const uint8_t *b = p->buf; while (i < p->buf_size) { @@ -197,10 +197,11 @@ static int amrnb_probe(AVProbeData *p) } } else { valid = 0; +invalid++; i++; } } -if (valid > 100) +if (valid > 100 && valid > invalid) return AVPROBE_SCORE_EXTENSION / 2 + 1; return 0; } @@ -234,7 +235,7 @@ AVInputFormat ff_amrnb_demuxer = { #if CONFIG_AMRWB_DEMUXER static int amrwb_probe(AVProbeData *p) { -int mode, i = 0, valid = 0; +int mode, i = 0, valid = 0, invalid = 0; const uint8_t *b = p->buf; while (i < p->buf_size) { @@ -253,10 +254,11 @@ static int amrwb_probe(AVProbeData *p) } } else { valid = 0; +invalid++; i++; } } -if (valid > 100) +if (valid > 100 && valid > invalid) return AVPROBE_SCORE_EXTENSION / 2 - 1; return 0; } -- 1.7.10.4 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 2/3] avformat/vivo: improve probing of some files
On 4/4/18, Michael Niedermayer wrote: > On Wed, Apr 04, 2018 at 04:09:36PM +0200, Paul B Mahol wrote: >> Signed-off-by: Paul B Mahol >> --- >> libavformat/vivo.c | 5 +++-- >> 1 file changed, 3 insertions(+), 2 deletions(-) >> >> diff --git a/libavformat/vivo.c b/libavformat/vivo.c >> index c9e9c37f37..6a88a09a01 100644 >> --- a/libavformat/vivo.c >> +++ b/libavformat/vivo.c >> @@ -59,9 +59,10 @@ static int vivo_probe(AVProbeData *p) >> if (c & 0x80 || length > 1024 || length < 21) >> return 0; >> >> -if (memcmp(buf, "\r\nVersion:Vivo/", 15)) >> +buf += 2; >> +if (memcmp(buf, "Version:Vivo/", 13)) >> return 0; > > what is in the 2 bytes that are not checked anymore ? Irrelevant bytes. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 2/3] avformat/vivo: improve probing of some files
On Wed, Apr 04, 2018 at 04:09:36PM +0200, Paul B Mahol wrote: > Signed-off-by: Paul B Mahol > --- > libavformat/vivo.c | 5 +++-- > 1 file changed, 3 insertions(+), 2 deletions(-) > > diff --git a/libavformat/vivo.c b/libavformat/vivo.c > index c9e9c37f37..6a88a09a01 100644 > --- a/libavformat/vivo.c > +++ b/libavformat/vivo.c > @@ -59,9 +59,10 @@ static int vivo_probe(AVProbeData *p) > if (c & 0x80 || length > 1024 || length < 21) > return 0; > > -if (memcmp(buf, "\r\nVersion:Vivo/", 15)) > +buf += 2; > +if (memcmp(buf, "Version:Vivo/", 13)) > return 0; what is in the 2 bytes that are not checked anymore ? [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB If you fake or manipulate statistics in a paper in physics you will never get a job again. If you fake or manipulate statistics in a paper in medicin you will get a job for life at the pharma industry. signature.asc Description: PGP signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] display: Add AVDisplayOrientation API
On Wed, Apr 04, 2018 at 05:30:24PM +0200, Vittorio Giovara wrote: > The transformation operations that can be described by a display matrix > are not limited to pure rotation, but include horizontal and vertical > flip, as well as transpose and antitranspose. Unfortunately the current > API can only return a rotation angle in degrees, and is not designed to > detect flip operations or a combination of rotation and flip. > > So implement an additional API to analyze the display matrix and return > the most common rotation operations (multiples of 90º) as well flips or > a combination thereof. This function returns a bitfield mask composed of > AVDisplayOrientation elements that describe which rendering operations > should be performed on the frame. The existing API is still available > and useful in case of custom rotations. > > Signed-off-by: Vittorio Giovara > --- > Note: the new operations describe a clockwise rotation, while the > old API provided a counterclockwise rotation. I always felt this was > a mistake as it's counterintuitive and suprising to new users, so I > didn't want to cargo-cult it to a new API. What do people think about it? > > See also https://github.com/FFMS/ffms2/issues/317 for flipped samples, code, > and additional discussion. > > Missing changelog entry and version bump. > Vittorio > > libavutil/display.c | 92 > + > libavutil/display.h | 53 ++ > 2 files changed, 145 insertions(+) It might be more usefull to fully factorize the matrix than these special cases for example the matrix can be described by these 4 scalars 1. rotation 2. horizontal scale 3. vertical scale 4. shear (there are more parameters like translation and z specific changes but IIUC these have no meaning ?) Note fliping in above would be a negative scale value shear could be specified as the angle between the x/y basis vectors The reason i suggest this is that these 4 values are easier to understand for a human and should allow reconstructing an equivalent transform matrix. While at the same time not limiting things to a subset of special cases [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Many things microsoft did are stupid, but not doing something just because microsoft did it is even more stupid. If everything ms did were stupid they would be bankrupt already. signature.asc Description: PGP signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avformat/rawenc: check stream type
On 4/5/2018 12:09 AM, Michael Niedermayer wrote: This does not work breaks fate-unknown_layout-ac3 Silly mistake. Fixed locally. also the tests mayb too strict, there are similar codec_ids like mpeg1/2 or jpeg variants which are all basically the same from a muxers point of view Will change to a switch block to take care of these promiscuous cases. Regards, Gyan ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avcodec/decode: fix warning when decoding pseudo paletted formats
On Wed, Apr 04, 2018 at 06:07:20PM +0200, wm4 wrote: > The pseudo palette allocation is optional now. But if it's still > allocated (like the internal get_buffer2 implementation does, for > compatibility), it shouldn't print a warning. > --- > libavcodec/decode.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/libavcodec/decode.c b/libavcodec/decode.c > index d883a5f9fc..421a8f1a35 100644 > --- a/libavcodec/decode.c > +++ b/libavcodec/decode.c > @@ -1779,6 +1779,8 @@ static void validate_avframe_allocation(AVCodecContext > *avctx, AVFrame *frame) > int flags = desc ? desc->flags : 0; > if (num_planes == 1 && (flags & AV_PIX_FMT_FLAG_PAL)) > num_planes = 2; > +if ((flags & FF_PSEUDOPAL) && frame->data[1]) > +num_planes = 2; > for (i = 0; i < num_planes; i++) { > av_assert0(frame->data[i]); > } LGTM thx [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB I know you won't believe me, but the highest form of Human Excellence is to question oneself and others. -- Socrates signature.asc Description: PGP signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] avformat/mov: Fix parsing of tfdt when using sample descriptors.
Signed-off-by: Jacob Trimble --- libavformat/mov.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index e7c32e6148..97b1462aab 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -4601,7 +4601,7 @@ static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom) return AVERROR_INVALIDDATA; } sc = st->priv_data; -if (sc->pseudo_stream_id + 1 != frag->stsd_id) +if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1) return 0; version = avio_r8(pb); avio_rb24(pb); /* flags */ -- 2.17.0.484.g0c8726318c-goog ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avformat/rawenc: check stream type
On Wed, Apr 04, 2018 at 03:53:25PM +0530, Gyan Doshi wrote: > rawenc.c | 10 ++ > 1 file changed, 10 insertions(+) > c144b841348e9af26d80e0014daf63c5b2477467 > 0001-avformat-rawenc-check-stream-type.patch > From f86916b9e1128a4e41501f4d5b189749a344862f Mon Sep 17 00:00:00 2001 > From: Gyan Doshi > Date: Wed, 4 Apr 2018 15:45:18 +0530 > Subject: [PATCH] avformat/rawenc: check stream type > > Validate codec of stream to be muxed except for data muxer. > --- > libavformat/rawenc.c | 10 ++ > 1 file changed, 10 insertions(+) > > diff --git a/libavformat/rawenc.c b/libavformat/rawenc.c > index 809ca23b1a..77cbc5f6fc 100644 > --- a/libavformat/rawenc.c > +++ b/libavformat/rawenc.c > @@ -39,6 +39,16 @@ static int force_one_stream(AVFormatContext *s) > s->oformat->name); > return AVERROR(EINVAL); > } > + > +if (strcmp("data", s->oformat->name)) { > +if (s->oformat->audio_codec != AV_CODEC_ID_NONE && > +s->oformat->audio_codec != s->streams[0]->codecpar->codec_id || > +s->oformat->video_codec != s->streams[0]->codecpar->codec_id) { > +av_log(s, AV_LOG_ERROR, "Stream not of type %s\n", > + s->oformat->name); This does not work breaks fate-unknown_layout-ac3 also the tests mayb too strict, there are similar codec_ids like mpeg1/2 or jpeg variants which are all basically the same from a muxers point of view [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Many that live deserve death. And some that die deserve life. Can you give it to them? Then do not be too eager to deal out death in judgement. For even the very wise cannot see all ends. -- Gandalf signature.asc Description: PGP signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] avcodec/decode: fix warning when decoding pseudo paletted formats
The pseudo palette allocation is optional now. But if it's still allocated (like the internal get_buffer2 implementation does, for compatibility), it shouldn't print a warning. --- libavcodec/decode.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/decode.c b/libavcodec/decode.c index d883a5f9fc..421a8f1a35 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -1779,6 +1779,8 @@ static void validate_avframe_allocation(AVCodecContext *avctx, AVFrame *frame) int flags = desc ? desc->flags : 0; if (num_planes == 1 && (flags & AV_PIX_FMT_FLAG_PAL)) num_planes = 2; +if ((flags & FF_PSEUDOPAL) && frame->data[1]) +num_planes = 2; for (i = 0; i < num_planes; i++) { av_assert0(frame->data[i]); } -- 2.16.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] display: Add AVDisplayOrientation API
The transformation operations that can be described by a display matrix are not limited to pure rotation, but include horizontal and vertical flip, as well as transpose and antitranspose. Unfortunately the current API can only return a rotation angle in degrees, and is not designed to detect flip operations or a combination of rotation and flip. So implement an additional API to analyze the display matrix and return the most common rotation operations (multiples of 90º) as well flips or a combination thereof. This function returns a bitfield mask composed of AVDisplayOrientation elements that describe which rendering operations should be performed on the frame. The existing API is still available and useful in case of custom rotations. Signed-off-by: Vittorio Giovara --- Note: the new operations describe a clockwise rotation, while the old API provided a counterclockwise rotation. I always felt this was a mistake as it's counterintuitive and suprising to new users, so I didn't want to cargo-cult it to a new API. What do people think about it? See also https://github.com/FFMS/ffms2/issues/317 for flipped samples, code, and additional discussion. Missing changelog entry and version bump. Vittorio libavutil/display.c | 92 + libavutil/display.h | 53 ++ 2 files changed, 145 insertions(+) diff --git a/libavutil/display.c b/libavutil/display.c index f7500948ff..839961ec20 100644 --- a/libavutil/display.c +++ b/libavutil/display.c @@ -22,6 +22,7 @@ #include #include +#include "avstring.h" #include "display.h" #include "mathematics.h" @@ -73,3 +74,94 @@ void av_display_matrix_flip(int32_t matrix[9], int hflip, int vflip) for (i = 0; i < 9; i++) matrix[i] *= flip[i % 3]; } + +uint32_t av_display_orientation_get(int32_t matrix_src[9]) +{ +int32_t matrix[9]; +uint32_t orientation = 0; +int64_t det = (int64_t)matrix_src[0] * matrix_src[4] - (int64_t)matrix_src[1] * matrix_src[3]; + +/* Duplicate matrix so that the input one is not modified in case of flip. */ +memcpy(matrix, matrix_src, sizeof(*matrix_src) * 9); + +if (det < 0) { +/* Always assume an horizontal flip for simplicity, it can be + * changed later if rotation is 180º. */ +orientation = AV_FLIP_HORIZONTAL; +av_display_matrix_flip(matrix, 1, 0); +} + +if (matrix[1] == (1 << 16) && matrix[3] == -(1 << 16)) { +orientation |= AV_ROTATION_90; +} else if (matrix[0] == -(1 << 16) && matrix[4] == -(1 << 16)) { +if (det < 0) +orientation = AV_FLIP_VERTICAL; +else +orientation |= AV_ROTATION_180; +} else if (matrix[1] == -(1 << 16) && matrix[3] == (1 << 16)) { +orientation |= AV_ROTATION_270; +} else if (matrix[0] == (1 << 16) && matrix[4] == (1 << 16)) { +orientation |= AV_IDENTITY; +} else { +orientation |= AV_ROTATION_CUSTOM; +} + +return orientation; +} + +void av_display_orientation_set(int32_t matrix[9], uint32_t orientation, double angle) +{ +int hflip = !!(orientation & AV_FLIP_HORIZONTAL); +int vflip = !!(orientation & AV_FLIP_VERTICAL); + +memset(matrix, 0, sizeof(*matrix) * 9); +matrix[8] = 1 << 30; + +if (orientation & AV_IDENTITY) { +matrix[0] = 1 << 16; +matrix[4] = 1 << 16; +} else if (orientation & AV_ROTATION_90) { +matrix[1] = 1 << 16; +matrix[3] = -(1 << 16); +} else if (orientation & AV_ROTATION_180) { +matrix[0] = -(1 << 16); +matrix[4] = -(1 << 16); +} else if (orientation & AV_ROTATION_270) { +matrix[1] = -(1 << 16); +matrix[3] = 1 << 16; +} else if (orientation & AV_ROTATION_CUSTOM) { +av_display_rotation_set(matrix, angle); +} + +av_display_matrix_flip(matrix, hflip, vflip); +} + +void av_display_orientation_name(uint32_t orientation, char *buf, size_t buf_size) +{ +if (orientation == 0) { +av_strlcpy(buf, "identity", buf_size); +return; +} + +if (orientation & AV_ROTATION_90) +av_strlcpy(buf, "rotation_90", buf_size); +else if (orientation & AV_ROTATION_180) +av_strlcpy(buf, "rotation_180", buf_size); +else if (orientation & AV_ROTATION_270) +av_strlcpy(buf, "rotation_270", buf_size); +else if (orientation & AV_ROTATION_CUSTOM) +av_strlcpy(buf, "rotation_custom", buf_size); +else +buf[0] = '\0'; + +if (orientation & AV_FLIP_HORIZONTAL) { +if (buf[0] != '\0') +av_strlcat(buf, "+", buf_size); +av_strlcat(buf, "hflip", buf_size); +} +if (orientation & AV_FLIP_VERTICAL) { +if (buf[0] != '\0') +av_strlcat(buf, "+", buf_size); +av_strlcat(buf, "vflip", buf_size); +} +} diff --git a/libavutil/display.h b/libavutil/display.h index 2d869fcd16..a057453b20 100644 --- a/libavutil/display.h +++ b/libavutil
Re: [FFmpeg-devel] [PATCH 1/3] avcodec: add siren audio decoder
On 4/4/18, James Almer wrote: > On 4/4/2018 11:09 AM, Paul B Mahol wrote: >> Signed-off-by: Paul B Mahol >> --- >> libavcodec/Makefile | 1 + >> libavcodec/allcodecs.c | 1 + >> libavcodec/avcodec.h| 1 + >> libavcodec/codec_desc.c | 8 + >> libavcodec/siren.c | 847 >> >> 5 files changed, 858 insertions(+) >> create mode 100644 libavcodec/siren.c > > [...] > >> +static av_cold int siren_init(AVCodecContext *avctx) >> +{ >> +SirenContext *s = avctx->priv_data; >> +int i; >> + >> +avctx->channels = 1; >> +avctx->channel_layout = AV_CH_LAYOUT_MONO; >> +avctx->sample_fmt = AV_SAMPLE_FMT_S16; >> + >> +s->number_of_coefs = 320; >> +s->rate_control_bits = 4; >> +s->rate_control_possibilities = 16; >> +s->checksum_bits = 0; >> +s->esf_adjustment = 7; >> +s->number_of_regions = 14; >> +s->scale_factor = 1; >> +s->bits_per_frame = avctx->sample_rate / 50; >> +s->region_size = 20; >> +s->dw1 = s->dw2 = s->dw3 = s->dw4 = 1; >> + >> +for (i = 0; i < 64; i++) { >> +float region_power = powf(10, (i - 24) * STEPSIZE); >> + >> +s->standard_deviation[i] = sqrtf(region_power); >> +s->deviation_inverse[i] = 1.f / s->standard_deviation[i]; >> +} >> + >> +for (i = 0; i < 320; i++) { >> +float angle = ((i + 0.5f) * M_PI_2) / 320.f; >> +s->window[i] = sinf(angle); >> +} >> + >> +ff_fft_init(&s->fft_ctx, 10, 0); > > Missing fft dependency in configure. ok > >> + >> +return 0; >> +} > > [...] > >> + >> +static int categorize_regions(int number_of_regions, int >> number_of_available_bits, >> + int *absolute_region_power_index, int >> *power_categories, >> + int *category_balance) >> +{ >> +int region, delta, i, temp; >> +int expected_number_of_code_bits; >> +int min, max; >> +int offset, >> +num_rate_control_possibilities, >> +raw_value, raw_max_idx = 0, raw_min_idx = 0; >> +int max_rate_categories[28]; >> +int min_rate_categories[28]; >> +int temp_category_balances[64]; >> +int *min_rate_ptr = NULL; >> +int *max_rate_ptr = NULL; >> + >> +if (number_of_regions == 14) { >> +num_rate_control_possibilities = 16; >> +if (number_of_available_bits > 320) >> +number_of_available_bits = >> +((number_of_available_bits - 320) * 5 / 8) + 320; >> +} else { >> +num_rate_control_possibilities = 32; >> +if (number_of_regions == 28 && number_of_available_bits > 640) >> +number_of_available_bits = >> +((number_of_available_bits - 640) * 5 / 8) + 640; >> +} >> + >> +offset = -32; >> +for (delta = 32; number_of_regions > 0 && delta > 0; delta /= 2) { >> +expected_number_of_code_bits = 0; >> +for (region = 0; region < number_of_regions; region++) { >> +i = (delta + offset - >> + absolute_region_power_index[region]) >> 1; >> +if (i > 7) >> +i = 7; >> +else if (i < 0) >> +i = 0; > > av_clip_uintp2() ok > >> + >> +power_categories[region] = i; >> +expected_number_of_code_bits += expected_bits_table[i]; >> + >> +} >> +if (expected_number_of_code_bits >= number_of_available_bits - >> 32) >> +offset += delta; >> +} >> + >> +expected_number_of_code_bits = 0; >> +for (region = 0; region < number_of_regions; region++) { >> +i = (offset - absolute_region_power_index[region]) >> 1; >> +if (i > 7) >> +i = 7; >> +else if (i < 0) >> +i = 0; > > Same. ok > >> +max_rate_categories[region] = min_rate_categories[region] = >> +power_categories[region] = i; >> +expected_number_of_code_bits += expected_bits_table[i]; >> +} > > [...] > >> +static int siren_decode(AVCodecContext *avctx, void *data, >> +int *got_frame, AVPacket *pkt) >> +{ >> +SirenContext *s = avctx->priv_data; >> +AVFrame *frame = data; >> +int number_of_valid_coefs = 20 * s->number_of_regions; >> +int number_of_available_bits = >> +s->bits_per_frame - s->sample_rate_bits - s->checksum_bits; > > s->checksum_bits seems to always be 0, unless I'm missing something. > >> +int envelope_bits, ret; >> +int frame_error = 0, i, rate_control = 0; >> +int checksum, calculated_checksum; >> + >> +if (s->checksum_bits > 0) >> +memcpy(s->input_frame, pkt->data, FFMIN(pkt->size, 80)); > > sizeof(s->input_frame) instead of 80? > ok >> +if ((ret = init_get_bits8(&s->gb, pkt->data, pkt->size)) < 0) >> +return ret; >> + >> +envelope_bits = >> +decode_envelope(s, &s->gb, s->number_of_regions, >> +s->decoder_standard_deviation, >> +
Re: [FFmpeg-devel] [PATCH 1/3] avcodec: add siren audio decoder
On 4/4/2018 11:09 AM, Paul B Mahol wrote: > Signed-off-by: Paul B Mahol > --- > libavcodec/Makefile | 1 + > libavcodec/allcodecs.c | 1 + > libavcodec/avcodec.h| 1 + > libavcodec/codec_desc.c | 8 + > libavcodec/siren.c | 847 > > 5 files changed, 858 insertions(+) > create mode 100644 libavcodec/siren.c [...] > +static av_cold int siren_init(AVCodecContext *avctx) > +{ > +SirenContext *s = avctx->priv_data; > +int i; > + > +avctx->channels = 1; > +avctx->channel_layout = AV_CH_LAYOUT_MONO; > +avctx->sample_fmt = AV_SAMPLE_FMT_S16; > + > +s->number_of_coefs = 320; > +s->rate_control_bits = 4; > +s->rate_control_possibilities = 16; > +s->checksum_bits = 0; > +s->esf_adjustment = 7; > +s->number_of_regions = 14; > +s->scale_factor = 1; > +s->bits_per_frame = avctx->sample_rate / 50; > +s->region_size = 20; > +s->dw1 = s->dw2 = s->dw3 = s->dw4 = 1; > + > +for (i = 0; i < 64; i++) { > +float region_power = powf(10, (i - 24) * STEPSIZE); > + > +s->standard_deviation[i] = sqrtf(region_power); > +s->deviation_inverse[i] = 1.f / s->standard_deviation[i]; > +} > + > +for (i = 0; i < 320; i++) { > +float angle = ((i + 0.5f) * M_PI_2) / 320.f; > +s->window[i] = sinf(angle); > +} > + > +ff_fft_init(&s->fft_ctx, 10, 0); Missing fft dependency in configure. > + > +return 0; > +} [...] > + > +static int categorize_regions(int number_of_regions, int > number_of_available_bits, > + int *absolute_region_power_index, int > *power_categories, > + int *category_balance) > +{ > +int region, delta, i, temp; > +int expected_number_of_code_bits; > +int min, max; > +int offset, > +num_rate_control_possibilities, > +raw_value, raw_max_idx = 0, raw_min_idx = 0; > +int max_rate_categories[28]; > +int min_rate_categories[28]; > +int temp_category_balances[64]; > +int *min_rate_ptr = NULL; > +int *max_rate_ptr = NULL; > + > +if (number_of_regions == 14) { > +num_rate_control_possibilities = 16; > +if (number_of_available_bits > 320) > +number_of_available_bits = > +((number_of_available_bits - 320) * 5 / 8) + 320; > +} else { > +num_rate_control_possibilities = 32; > +if (number_of_regions == 28 && number_of_available_bits > 640) > +number_of_available_bits = > +((number_of_available_bits - 640) * 5 / 8) + 640; > +} > + > +offset = -32; > +for (delta = 32; number_of_regions > 0 && delta > 0; delta /= 2) { > +expected_number_of_code_bits = 0; > +for (region = 0; region < number_of_regions; region++) { > +i = (delta + offset - > + absolute_region_power_index[region]) >> 1; > +if (i > 7) > +i = 7; > +else if (i < 0) > +i = 0; av_clip_uintp2() > + > +power_categories[region] = i; > +expected_number_of_code_bits += expected_bits_table[i]; > + > +} > +if (expected_number_of_code_bits >= number_of_available_bits - 32) > +offset += delta; > +} > + > +expected_number_of_code_bits = 0; > +for (region = 0; region < number_of_regions; region++) { > +i = (offset - absolute_region_power_index[region]) >> 1; > +if (i > 7) > +i = 7; > +else if (i < 0) > +i = 0; Same. > +max_rate_categories[region] = min_rate_categories[region] = > +power_categories[region] = i; > +expected_number_of_code_bits += expected_bits_table[i]; > +} [...] > +static int siren_decode(AVCodecContext *avctx, void *data, > +int *got_frame, AVPacket *pkt) > +{ > +SirenContext *s = avctx->priv_data; > +AVFrame *frame = data; > +int number_of_valid_coefs = 20 * s->number_of_regions; > +int number_of_available_bits = > +s->bits_per_frame - s->sample_rate_bits - s->checksum_bits; s->checksum_bits seems to always be 0, unless I'm missing something. > +int envelope_bits, ret; > +int frame_error = 0, i, rate_control = 0; > +int checksum, calculated_checksum; > + > +if (s->checksum_bits > 0) > +memcpy(s->input_frame, pkt->data, FFMIN(pkt->size, 80)); sizeof(s->input_frame) instead of 80? > +if ((ret = init_get_bits8(&s->gb, pkt->data, pkt->size)) < 0) > +return ret; > + > +envelope_bits = > +decode_envelope(s, &s->gb, s->number_of_regions, > +s->decoder_standard_deviation, > +s->absolute_region_power_index, s->esf_adjustment); > + > +number_of_available_bits -= envelope_bits; > + > +for (i = 0; i < s->rate_control_bits; i++) { > +rate_control <<= 1; > +
[FFmpeg-devel] [PATCH 2/3] avformat/vivo: improve probing of some files
Signed-off-by: Paul B Mahol --- libavformat/vivo.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libavformat/vivo.c b/libavformat/vivo.c index c9e9c37f37..6a88a09a01 100644 --- a/libavformat/vivo.c +++ b/libavformat/vivo.c @@ -59,9 +59,10 @@ static int vivo_probe(AVProbeData *p) if (c & 0x80 || length > 1024 || length < 21) return 0; -if (memcmp(buf, "\r\nVersion:Vivo/", 15)) +buf += 2; +if (memcmp(buf, "Version:Vivo/", 13)) return 0; -buf += 15; +buf += 13; if (*buf < '0' || *buf > '2') return 0; -- 2.11.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH 1/3] avcodec: add siren audio decoder
Signed-off-by: Paul B Mahol --- libavcodec/Makefile | 1 + libavcodec/allcodecs.c | 1 + libavcodec/avcodec.h| 1 + libavcodec/codec_desc.c | 8 + libavcodec/siren.c | 847 5 files changed, 858 insertions(+) create mode 100644 libavcodec/siren.c diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 4b8ad121db..86cea2d1aa 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -563,6 +563,7 @@ OBJS-$(CONFIG_SIPR_DECODER)+= sipr.o acelp_pitch_delay.o \ celp_math.o acelp_vectors.o \ acelp_filters.o celp_filters.o \ sipr16k.o +OBJS-$(CONFIG_SIREN_DECODER) += siren.o OBJS-$(CONFIG_SMACKAUD_DECODER)+= smacker.o OBJS-$(CONFIG_SMACKER_DECODER) += smacker.o OBJS-$(CONFIG_SMC_DECODER) += smc.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 4d4ef530e4..830c84ed45 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -457,6 +457,7 @@ extern AVCodec ff_sbc_encoder; extern AVCodec ff_sbc_decoder; extern AVCodec ff_shorten_decoder; extern AVCodec ff_sipr_decoder; +extern AVCodec ff_siren_decoder; extern AVCodec ff_smackaud_decoder; extern AVCodec ff_sonic_encoder; extern AVCodec ff_sonic_decoder; diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index fb0c6fae70..b63746b105 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -637,6 +637,7 @@ enum AVCodecID { AV_CODEC_ID_APTX, AV_CODEC_ID_APTX_HD, AV_CODEC_ID_SBC, +AV_CODEC_ID_SIREN, /* subtitle codecs */ AV_CODEC_ID_FIRST_SUBTITLE = 0x17000, ///< A dummy ID pointing at the start of subtitle codecs. diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 79552a910d..730cf5482a 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -2878,6 +2878,14 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("SBC (low-complexity subband codec)"), .props = AV_CODEC_PROP_LOSSY, }, +{ +.id= AV_CODEC_ID_SIREN, +.type = AVMEDIA_TYPE_AUDIO, +.name = "siren", +.long_name = NULL_IF_CONFIG_SMALL("Siren"), +.props = AV_CODEC_PROP_LOSSY, +}, + /* subtitle codecs */ { diff --git a/libavcodec/siren.c b/libavcodec/siren.c new file mode 100644 index 00..d49a26f2a9 --- /dev/null +++ b/libavcodec/siren.c @@ -0,0 +1,847 @@ +/* + * Siren audio decoder + * Copyright (c) 2012 Youness Alaoui + * Copyright (c) 2018 Paul B Mahol + * + * 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 + */ + +#include "avcodec.h" +#include "fft.h" +#include "get_bits.h" +#include "internal.h" +#include "mathops.h" + +#define STEPSIZE0.3010299957 + +static uint16_t checksum_table[4] = { 0x7F80, 0x7878, 0x, 0x }; +static const uint8_t index_table[8] = {4, 4, 3, 3, 2, 2, 1, 0}; +static const uint8_t vector_dimension[8] = { 2, 2, 2, 4, 4, 5, 5, 1 }; +static const uint8_t number_of_vectors[8] = { 10, 10, 10, 5, 5, 4, 4, 20 }; +static const uint8_t expected_bits_table[8] = { 52, 47, 43, 37, 29, 22, 16, 0 }; +static const int8_t differential_decoder_tree[27][24][2] = { + {{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, -12}, {-11, -10}, {-8, -9}, {-7, -6}, {-13, 12}, {-5, -4}, {0, 13}, {-3, -14}, {-2, 14}, {-1, 15}, {-15, 16}, {-16, 17}, {-17, 18}, {19, 20}, {21, 22}, {-18, -19}, {-20, -21}, {-22, -23}, {-32, -32}}, + {{1, 2}, {3, 4}, {5, 6}, {7, 8}, {-10, -9}, {-8, -11}, {-7, -6}, {9, -5}, {10, -12}, {-4, 11}, {-13, -3}, {12, -2}, {13, -14}, {-1, 14}, {15, -15}, {0, 16}, {-16, 17}, {-17, 18}, {-18, 19}, {20, 21},{22, -19}, {-20, -21}, {-22, -23}, {-32, -32}}, + {{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {-12, 11}, {-11, -13}, {-10, -9}, {12, -14}, {-8, -7}, {-15, -6}, {13, -5}, {-16, -4}, {14, -17}, {15, -3}, {16, -18}, {-2, 17}, {18, -19}, {-1, 19}, {-20, 20}, {0, 21}, {22, -21}, {-22, -23}, {-32, -32}}, + {{1, 2}, {3, 4}, {5, 6}, {-11, -10}, {7, -12}, {8, -9}, {9, -13}, {-14, 10}, {-8, -15}, {-16, 11}, {-7, 12}, {-17, -6}, {13, 14}, {-18, 15}, {-5, -4
[FFmpeg-devel] [PATCH 3/3] avformat/vivo: add support for siren codec
Signed-off-by: Paul B Mahol --- libavformat/vivo.c | 5 + 1 file changed, 5 insertions(+) diff --git a/libavformat/vivo.c b/libavformat/vivo.c index 6a88a09a01..1339a609b9 100644 --- a/libavformat/vivo.c +++ b/libavformat/vivo.c @@ -232,6 +232,11 @@ static int vivo_read_header(AVFormatContext *s) ast->codecpar->bits_per_coded_sample = 8; ast->codecpar->block_align = 24; ast->codecpar->bit_rate = 6400; +} else { +ast->codecpar->codec_id = AV_CODEC_ID_SIREN; +ast->codecpar->bits_per_coded_sample = 16; +ast->codecpar->block_align = 40; +ast->codecpar->bit_rate = 6400; } ast->start_time= 0; -- 2.11.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH v2 1/1] avformat/http: flushing tcp receive buffer when it is write only mode
> On 4 Apr 2018, at 19:08, vdi...@akamai.com wrote: > > From: Vishwanath Dixit > > In write only mode, the TCP receive buffer's data keeps growing with > http response messages and the buffer eventually becomes full. > This results in zero tcp window size, which in turn causes unwanted > issues, like, terminated tcp connection. The issue is apparent when > http persistent connection is enabled in hls/dash live streaming use > cases. To overcome this issue, the logic here reads the buffer data > when a file transfer is completed, so that any accumulated data in > the recieve buffer gets flushed out. > --- > libavformat/http.c | 12 > 1 file changed, 12 insertions(+) > > diff --git a/libavformat/http.c b/libavformat/http.c > index 983034f..0c39e9c 100644 > --- a/libavformat/http.c > +++ b/libavformat/http.c > @@ -1627,6 +1627,18 @@ static int http_shutdown(URLContext *h, int flags) > ((flags & AVIO_FLAG_READ) && s->chunked_post && s->listen)) { > ret = ffurl_write(s->hd, footer, sizeof(footer) - 1); > ret = ret > 0 ? 0 : ret; > +/* flush the receive buffer when it is write only mode */ > +if (!(flags & AVIO_FLAG_READ)) { > +char buf[1024]; > +int read_ret; > +s->hd->flags |= AVIO_FLAG_NONBLOCK; > +read_ret = ffurl_read(s->hd, buf, sizeof(buf)); > +s->hd->flags &= ~AVIO_FLAG_NONBLOCK; > +if (read_ret < 0 && read_ret != AVERROR(EAGAIN)) { > +av_log(h, AV_LOG_ERROR, "URL read error: %d\n", read_ret); > +ret = read_ret; > +} > +} > s->end_chunked_post = 1; > } > > -- > 1.9.1 > LGTM, but i cannot sure the buf and read_ret define in the paragraph is a good style. Thanks Steven ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 1/1] avformat/http: flushing tcp receive buffer when it is write only mode
On 3/28/18 11:00 AM, Steven Liu wrote: > > >> On 28 Mar 2018, at 12:52, vdi...@akamai.com wrote: >> >> From: Vishwanath Dixit >> >> In write only mode, the TCP receive buffer keeps growing and eventually >> becomes full. This results in zero tcp window size, which in turn causes >> unwanted issues, like, terminated tcp connection. The issue is apparent >> when http persistent connection is enabled in hls/dash streaming use >> cases. To overcome this issue, the logic here reads and discards the data >> from the tcp socket. >> --- >> libavformat/http.c | 7 +++ >> 1 file changed, 7 insertions(+) >> >> diff --git a/libavformat/http.c b/libavformat/http.c >> index 983034f..e6d414b 100644 >> --- a/libavformat/http.c >> +++ b/libavformat/http.c >> @@ -1627,6 +1627,13 @@ static int http_shutdown(URLContext *h, int flags) >> ((flags & AVIO_FLAG_READ) && s->chunked_post && s->listen)) { >> ret = ffurl_write(s->hd, footer, sizeof(footer) - 1); >> ret = ret > 0 ? 0 : ret; >> +/* flush the receive buffer when it is write only mode */ >> +if (!(flags & AVIO_FLAG_READ)) { >> +char buf[1024]; >> +s->hd->flags |= AVIO_FLAG_NONBLOCK; >> +ffurl_read(s->hd, buf, sizeof(buf)); > ffurl_read have a int return value. > > 407 int ffurl_read(URLContext *h, unsigned char *buf, int size) > 408 { > 409 if (!(h->flags & AVIO_FLAG_READ)) > 410 return AVERROR(EIO); > 411 return retry_transfer_wrapper(h, buf, size, 1, h->prot->url_read); > 412 } > > Thanks for the review comment. I have handled the return status of ffurl_read and have submitted a revised patch https://patchwork.ffmpeg.org/patch/8325/ >> +s->hd->flags &= ~AVIO_FLAG_NONBLOCK; >> +} >> s->end_chunked_post = 1; >> } >> >> -- >> 1.9.1 >> >> ___ >> ffmpeg-devel mailing list >> ffmpeg-devel@ffmpeg.org >> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > Thanks > Steven > > > > > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH v2 1/1] avformat/http: flushing tcp receive buffer when it is write only mode
From: Vishwanath Dixit In write only mode, the TCP receive buffer's data keeps growing with http response messages and the buffer eventually becomes full. This results in zero tcp window size, which in turn causes unwanted issues, like, terminated tcp connection. The issue is apparent when http persistent connection is enabled in hls/dash live streaming use cases. To overcome this issue, the logic here reads the buffer data when a file transfer is completed, so that any accumulated data in the recieve buffer gets flushed out. --- libavformat/http.c | 12 1 file changed, 12 insertions(+) diff --git a/libavformat/http.c b/libavformat/http.c index 983034f..0c39e9c 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -1627,6 +1627,18 @@ static int http_shutdown(URLContext *h, int flags) ((flags & AVIO_FLAG_READ) && s->chunked_post && s->listen)) { ret = ffurl_write(s->hd, footer, sizeof(footer) - 1); ret = ret > 0 ? 0 : ret; +/* flush the receive buffer when it is write only mode */ +if (!(flags & AVIO_FLAG_READ)) { +char buf[1024]; +int read_ret; +s->hd->flags |= AVIO_FLAG_NONBLOCK; +read_ret = ffurl_read(s->hd, buf, sizeof(buf)); +s->hd->flags &= ~AVIO_FLAG_NONBLOCK; +if (read_ret < 0 && read_ret != AVERROR(EAGAIN)) { +av_log(h, AV_LOG_ERROR, "URL read error: %d\n", read_ret); +ret = read_ret; +} +} s->end_chunked_post = 1; } -- 1.9.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] avformat/rawenc: check stream type
From f86916b9e1128a4e41501f4d5b189749a344862f Mon Sep 17 00:00:00 2001 From: Gyan Doshi Date: Wed, 4 Apr 2018 15:45:18 +0530 Subject: [PATCH] avformat/rawenc: check stream type Validate codec of stream to be muxed except for data muxer. --- libavformat/rawenc.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/libavformat/rawenc.c b/libavformat/rawenc.c index 809ca23b1a..77cbc5f6fc 100644 --- a/libavformat/rawenc.c +++ b/libavformat/rawenc.c @@ -39,6 +39,16 @@ static int force_one_stream(AVFormatContext *s) s->oformat->name); return AVERROR(EINVAL); } + +if (strcmp("data", s->oformat->name)) { +if (s->oformat->audio_codec != AV_CODEC_ID_NONE && +s->oformat->audio_codec != s->streams[0]->codecpar->codec_id || +s->oformat->video_codec != s->streams[0]->codecpar->codec_id) { +av_log(s, AV_LOG_ERROR, "Stream not of type %s\n", + s->oformat->name); +return AVERROR(EINVAL); +} +} return 0; } -- 2.12.2.windows.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] lavc/qsvenc: fix the hard code of height aligment checking
Signed-off-by: Zhong Li --- libavcodec/qsvenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c index afb953e..573c11e 100644 --- a/libavcodec/qsvenc.c +++ b/libavcodec/qsvenc.c @@ -1051,7 +1051,7 @@ static int submit_frame(QSVEncContext *q, const AVFrame *frame, } } else { /* make a copy if the input is not padded as libmfx requires */ -if (frame->height & 31 || frame->linesize[0] & (q->width_align - 1)) { +if (frame->height & (q->height_align - 1) || frame->linesize[0] & (q->width_align - 1)) { qf->frame->height = FFALIGN(frame->height, q->height_align); qf->frame->width = FFALIGN(frame->width, q->width_align); -- 1.8.3.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] lavf/qsvvpp: bypass vpp if not needed.
Currently vpp pipeline is always created, even for the unnecessary cases such as setting the option "vpp_qsv=w=1280:h=720" for an input with native resolution 1280x720. Thus introduces unnecessary performance dropping, so bypass vpp if not needed. Signed-off-by: Zhong Li --- libavfilter/vf_vpp_qsv.c | 28 +--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/libavfilter/vf_vpp_qsv.c b/libavfilter/vf_vpp_qsv.c index bd5fc32..6be7098 100644 --- a/libavfilter/vf_vpp_qsv.c +++ b/libavfilter/vf_vpp_qsv.c @@ -27,6 +27,7 @@ #include "libavutil/eval.h" #include "libavutil/avassert.h" #include "libavutil/pixdesc.h" +#include "libavutil/mathematics.h" #include "formats.h" #include "internal.h" @@ -249,6 +250,7 @@ static int config_output(AVFilterLink *outlink) QSVVPPParam param = { NULL }; QSVVPPCrop crop = { 0 }; mfxExtBuffer*ext_buf[ENH_FILTERS_COUNT]; +AVFilterLink*inlink = ctx->inputs[0]; outlink->w = vpp->out_width; outlink->h = vpp->out_height; @@ -320,14 +322,34 @@ static int config_output(AVFilterLink *outlink) param.ext_buf[param.num_ext_buf++] = (mfxExtBuffer*)&vpp->procamp_conf; } -return ff_qsvvpp_create(ctx, &vpp->qsv, ¶m); +if (vpp->use_frc || vpp->use_crop || vpp->deinterlace || vpp->denoise || +vpp->detail || vpp->procamp || inlink->w != outlink->w || inlink->h != outlink->h) +return ff_qsvvpp_create(ctx, &vpp->qsv, ¶m); +else { +av_log(ctx, AV_LOG_VERBOSE, "qsv vpp pass through mode.\n"); +if (inlink->hw_frames_ctx) +outlink->hw_frames_ctx = av_buffer_ref(inlink->hw_frames_ctx); +} + +return 0; } static int filter_frame(AVFilterLink *inlink, AVFrame *picref) { -VPPContext *vpp = inlink->dst->priv; +int ret = 0; +AVFilterContext *ctx = inlink->dst; +VPPContext *vpp = inlink->dst->priv; +AVFilterLink *outlink = ctx->outputs[0]; + +if (vpp->qsv) +ret = ff_qsvvpp_filter_frame(vpp->qsv, inlink, picref); +else { +if (picref->pts != AV_NOPTS_VALUE) +picref->pts = av_rescale_q(picref->pts, inlink->time_base, outlink->time_base); +ret = ff_filter_frame(outlink, picref); +} -return ff_qsvvpp_filter_frame(vpp->qsv, inlink, picref); +return ret; } static int query_formats(AVFilterContext *ctx) -- 1.8.3.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 06/11] avformat/dashenc: addition of @availabilityTimeOffset in MPD
On 4/2/18 9:36 AM, Jeyapal, Karthick wrote: > > > On 3/23/18 10:57 AM, vdi...@akamai.com wrote: >> From: Vishwanath Dixit >> >> availability time of Nth segment = availabilityStartTime + (N*segment >> duration) - availabilityTimeOffset. >> This field helps to reduce the latency by about a segment duration in >> streaming mode. >> --- >> libavformat/dashenc.c | 11 ++- >> 1 file changed, 10 insertions(+), 1 deletion(-) >> >> diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c >> index b62cb3e..d20bdba 100644 >> --- a/libavformat/dashenc.c >> +++ b/libavformat/dashenc.c >> @@ -85,6 +85,7 @@ typedef struct OutputStream { >> char filename[1024]; >> char full_path[1024]; >> char temp_path[1024]; >> +int64_t chunk_duration; > Remove this variable chunk_duration, and instead create a variable directly > for availabilityTimeOffset. Thanks for the review. I have submitted the revised patch https://patchwork.ffmpeg.org/patch/8312/ >> } OutputStream; >> >> typedef struct DASHContext { >> @@ -343,8 +344,12 @@ static void output_segment_list(OutputStream *os, >> AVIOContext *out, AVFormatCont >> if (c->use_template) { >> int timescale = c->use_timeline ? >> os->ctx->streams[0]->time_base.den : AV_TIME_BASE; >> avio_printf(out, "\t\t\t\t> timescale); >> -if (!c->use_timeline) >> +if (!c->use_timeline) { >> avio_printf(out, "duration=\"%d\" ", c->seg_duration); >> +if (c->streaming && os->chunk_duration) >> +avio_printf(out, "availabilityTimeOffset=\"%.3f\" ", >> +((double) c->seg_duration - os->chunk_duration) >> / AV_TIME_BASE); >> +} >> avio_printf(out, "initialization=\"%s\" media=\"%s\" >> startNumber=\"%d\">\n", c->init_seg_name, c->media_seg_name, c->use_timeline >> ? start_number : 1); >> if (c->use_timeline) { >> int64_t cur_time = 0; >> @@ -1283,6 +1288,10 @@ static int dash_write_packet(AVFormatContext *s, >> AVPacket *pkt) >> format_date_now(c->availability_start_time, >> sizeof(c->availability_start_time)); >> >> +if (!os->chunk_duration && pkt->duration) >> +os->chunk_duration = av_rescale_q(pkt->duration, st->time_base, >> + AV_TIME_BASE_Q); > Don’t use the term ‘chunk_duration’ here, as it is not clearly conceptualized > in this file. > Instead use the term ‘frame_duration’(local variable) to avoid confusion. Thanks for the review. I have submitted the revised patch https://patchwork.ffmpeg.org/patch/8312/ >> + >> if (c->use_template && !c->use_timeline) { >> elapsed_duration = pkt->pts - os->first_pts; >> seg_end_duration = (int64_t) os->segment_index * c->seg_duration; > > > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 05/11] avformat/dashenc: setting @availabilityStartTime when the first frame is ready
On 4/2/18 9:29 AM, Jeyapal, Karthick wrote: > > > On 3/23/18 10:56 AM, vdi...@akamai.com wrote: >> From: Vishwanath Dixit >> >> @availabilityStartTime specifies the anchor for the computation of the >> earliest >> availability time (in UTC) for any Segment in the Media Presentation. > Please be little more verbose for a clearer explanation. Thanks for the review. I have submitted the revised patch https://patchwork.ffmpeg.org/patch/8315/. >> --- >> libavformat/dashenc.c | 7 --- >> 1 file changed, 4 insertions(+), 3 deletions(-) >> >> diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c >> index 7b854b5..b62cb3e 100644 >> --- a/libavformat/dashenc.c >> +++ b/libavformat/dashenc.c >> @@ -740,9 +740,6 @@ static int write_manifest(AVFormatContext *s, int final) >> update_period = 500; >> avio_printf(out, "\tminimumUpdatePeriod=\"PT%"PRId64"S\"\n", >> update_period); >> avio_printf(out, "\tsuggestedPresentationDelay=\"PT%"PRId64"S\"\n", >> c->last_duration / AV_TIME_BASE); >> -if (!c->availability_start_time[0] && s->nb_streams > 0 && >> c->streams[0].nb_segments > 0) { >> -format_date_now(c->availability_start_time, >> sizeof(c->availability_start_time)); >> -} >> if (c->availability_start_time[0]) >> avio_printf(out, "\tavailabilityStartTime=\"%s\"\n", >> c->availability_start_time); >> format_date_now(now_str, sizeof(now_str)); >> @@ -1282,6 +1279,10 @@ static int dash_write_packet(AVFormatContext *s, >> AVPacket *pkt) >> if (os->first_pts == AV_NOPTS_VALUE) >> os->first_pts = pkt->pts; >> >> +if (!c->availability_start_time[0]) >> +format_date_now(c->availability_start_time, >> +sizeof(c->availability_start_time)); >> + >> if (c->use_template && !c->use_timeline) { >> elapsed_duration = pkt->pts - os->first_pts; >> seg_end_duration = (int64_t) os->segment_index * c->seg_duration; > > > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH 01/11] avformat/dashenc: renamed 'min_seg_duration' to 'seg_duration'
On 3/23/18 7:22 PM, Aurelien Jacobs wrote: > On Fri, Mar 23, 2018 at 02:32:30PM +0800, Steven Liu wrote: >> >> >>> On 23 Mar 2018, at 13:20, vdi...@akamai.com wrote: >>> >>> From: Vishwanath Dixit >>> >>> --- >>> doc/muxers.texi | 2 +- >>> libavformat/dashenc.c | 10 +- >>> 2 files changed, 6 insertions(+), 6 deletions(-) >>> >>> diff --git a/doc/muxers.texi b/doc/muxers.texi >>> index cb75c26..65eec92 100644 >>> --- a/doc/muxers.texi >>> +++ b/doc/muxers.texi >>> @@ -225,7 +225,7 @@ ffmpeg -re -i -map 0 -map 0 -c:a libfdk_aac >>> -c:v libx264 >>> @end example >>> >>> @table @option >>> -@item -min_seg_duration @var{microseconds} >>> +@item -seg_duration @var{microseconds} >>> Set the segment length in microseconds. >>> @item -window_size @var{size} >>> Set the maximum number of segments kept in the manifest. >>> diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c >>> index bdf8c8d..bdd5b56 100644 >>> --- a/libavformat/dashenc.c >>> +++ b/libavformat/dashenc.c >>> @@ -94,7 +94,7 @@ typedef struct DASHContext { >>> int nb_as; >>> int window_size; >>> int extra_window_size; >>> -int min_seg_duration; >>> +int seg_duration; >>> int remove_at_exit; >>> int use_template; >>> int use_timeline; >>> @@ -974,7 +974,7 @@ static int dash_init(AVFormatContext *s) >>> else >>> av_dict_set(&opts, "movflags", >>> "frag_custom+dash+delay_moov", 0); >>> } else { >>> -av_dict_set_int(&opts, "cluster_time_limit", >>> c->min_seg_duration / 1000, 0); >>> +av_dict_set_int(&opts, "cluster_time_limit", c->seg_duration / >>> 1000, 0); >>> av_dict_set_int(&opts, "cluster_size_limit", 5 * 1024 * 1024, >>> 0); // set a large cluster size limit >>> av_dict_set_int(&opts, "dash", 1, 0); >>> av_dict_set_int(&opts, "dash_track_number", i + 1, 0); >>> @@ -1020,7 +1020,7 @@ static int dash_init(AVFormatContext *s) >>> os->segment_index = 1; >>> } >>> >>> -if (!c->has_video && c->min_seg_duration <= 0) { >>> +if (!c->has_video && c->seg_duration <= 0) { >>> av_log(s, AV_LOG_WARNING, "no video stream and no min seg duration >>> set\n"); >>> return AVERROR(EINVAL); >>> } >>> @@ -1287,7 +1287,7 @@ static int dash_write_packet(AVFormatContext *s, >>> AVPacket *pkt) >>> if ((!c->has_video || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) && >>> pkt->flags & AV_PKT_FLAG_KEY && os->packets_written && >>> av_compare_ts(pkt->pts - os->start_pts, st->time_base, >>> - c->min_seg_duration, AV_TIME_BASE_Q) >= 0) { >>> + c->seg_duration, AV_TIME_BASE_Q) >= 0) { >>> int64_t prev_duration = c->last_duration; >>> >>> c->last_duration = av_rescale_q(pkt->pts - os->start_pts, >>> @@ -1427,7 +1427,7 @@ static const AVOption options[] = { >>> { "adaptation_sets", "Adaptation sets. Syntax: id=0,streams=0,1,2 >>> id=1,streams=3,4 and so on", OFFSET(adaptation_sets), AV_OPT_TYPE_STRING, { >>> 0 }, 0, 0, AV_OPT_FLAG_ENCODING_PARAM }, >>> { "window_size", "number of segments kept in the manifest", >>> OFFSET(window_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, E }, >>> { "extra_window_size", "number of segments kept outside of the manifest >>> before removing from disk", OFFSET(extra_window_size), AV_OPT_TYPE_INT, { >>> .i64 = 5 }, 0, INT_MAX, E }, >>> -{ "min_seg_duration", "minimum segment duration (in microseconds)", >>> OFFSET(min_seg_duration), AV_OPT_TYPE_INT, { .i64 = 500 }, 0, INT_MAX, >>> E }, >>> +{ "seg_duration", "minimum segment duration (in microseconds)", >>> OFFSET(seg_duration), AV_OPT_TYPE_INT, { .i64 = 500 }, 0, INT_MAX, E }, >> >> No, you can make the min_seg_duration deprecated, leave a warning message, >> update the info into the document, and add set_duration here, bump the >> version. >> So that can give the user some time to change the options from >> min_seg_duration to seg_duration. > > This is probably also a good oportunity to change seg_duration to > AV_OPT_TYPE_DURATION. Thanks for this input. I have made the suggested update. Revised patch is here: https://patchwork.ffmpeg.org/patch/8311/ > ___ > 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 01/11] avformat/dashenc: renamed 'min_seg_duration' to 'seg_duration'
On 3/23/18 12:02 PM, Steven Liu wrote: > > >> On 23 Mar 2018, at 13:20, vdi...@akamai.com wrote: >> >> From: Vishwanath Dixit >> >> --- >> doc/muxers.texi | 2 +- >> libavformat/dashenc.c | 10 +- >> 2 files changed, 6 insertions(+), 6 deletions(-) >> >> diff --git a/doc/muxers.texi b/doc/muxers.texi >> index cb75c26..65eec92 100644 >> --- a/doc/muxers.texi >> +++ b/doc/muxers.texi >> @@ -225,7 +225,7 @@ ffmpeg -re -i -map 0 -map 0 -c:a libfdk_aac -c:v >> libx264 >> @end example >> >> @table @option >> -@item -min_seg_duration @var{microseconds} >> +@item -seg_duration @var{microseconds} >> Set the segment length in microseconds. >> @item -window_size @var{size} >> Set the maximum number of segments kept in the manifest. >> diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c >> index bdf8c8d..bdd5b56 100644 >> --- a/libavformat/dashenc.c >> +++ b/libavformat/dashenc.c >> @@ -94,7 +94,7 @@ typedef struct DASHContext { >> int nb_as; >> int window_size; >> int extra_window_size; >> -int min_seg_duration; >> +int seg_duration; >> int remove_at_exit; >> int use_template; >> int use_timeline; >> @@ -974,7 +974,7 @@ static int dash_init(AVFormatContext *s) >> else >> av_dict_set(&opts, "movflags", >> "frag_custom+dash+delay_moov", 0); >> } else { >> -av_dict_set_int(&opts, "cluster_time_limit", >> c->min_seg_duration / 1000, 0); >> +av_dict_set_int(&opts, "cluster_time_limit", c->seg_duration / >> 1000, 0); >> av_dict_set_int(&opts, "cluster_size_limit", 5 * 1024 * 1024, >> 0); // set a large cluster size limit >> av_dict_set_int(&opts, "dash", 1, 0); >> av_dict_set_int(&opts, "dash_track_number", i + 1, 0); >> @@ -1020,7 +1020,7 @@ static int dash_init(AVFormatContext *s) >> os->segment_index = 1; >> } >> >> -if (!c->has_video && c->min_seg_duration <= 0) { >> +if (!c->has_video && c->seg_duration <= 0) { >> av_log(s, AV_LOG_WARNING, "no video stream and no min seg duration >> set\n"); >> return AVERROR(EINVAL); >> } >> @@ -1287,7 +1287,7 @@ static int dash_write_packet(AVFormatContext *s, >> AVPacket *pkt) >> if ((!c->has_video || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) && >> pkt->flags & AV_PKT_FLAG_KEY && os->packets_written && >> av_compare_ts(pkt->pts - os->start_pts, st->time_base, >> - c->min_seg_duration, AV_TIME_BASE_Q) >= 0) { >> + c->seg_duration, AV_TIME_BASE_Q) >= 0) { >> int64_t prev_duration = c->last_duration; >> >> c->last_duration = av_rescale_q(pkt->pts - os->start_pts, >> @@ -1427,7 +1427,7 @@ static const AVOption options[] = { >> { "adaptation_sets", "Adaptation sets. Syntax: id=0,streams=0,1,2 >> id=1,streams=3,4 and so on", OFFSET(adaptation_sets), AV_OPT_TYPE_STRING, { >> 0 }, 0, 0, AV_OPT_FLAG_ENCODING_PARAM }, >> { "window_size", "number of segments kept in the manifest", >> OFFSET(window_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, E }, >> { "extra_window_size", "number of segments kept outside of the manifest >> before removing from disk", OFFSET(extra_window_size), AV_OPT_TYPE_INT, { >> .i64 = 5 }, 0, INT_MAX, E }, >> -{ "min_seg_duration", "minimum segment duration (in microseconds)", >> OFFSET(min_seg_duration), AV_OPT_TYPE_INT, { .i64 = 500 }, 0, INT_MAX, E >> }, >> +{ "seg_duration", "minimum segment duration (in microseconds)", >> OFFSET(seg_duration), AV_OPT_TYPE_INT, { .i64 = 500 }, 0, INT_MAX, E }, > > No, you can make the min_seg_duration deprecated, leave a warning message, > update the info into the document, and add set_duration here, bump the > version. > So that can give the user some time to change the options from > min_seg_duration to seg_duration. Thanks for the review comment. I have made the suggested updates and have submitted the revised patch https://patchwork.ffmpeg.org/patch/8311/ >> { "remove_at_exit", "remove all segments when finished", >> OFFSET(remove_at_exit), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E }, >> { "use_template", "Use SegmentTemplate instead of SegmentList", >> OFFSET(use_template), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, E }, >> { "use_timeline", "Use SegmentTimeline in SegmentTemplate", >> OFFSET(use_timeline), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, E }, >> -- >> 1.9.1 >> >> ___ >> ffmpeg-devel mailing list >> ffmpeg-devel@ffmpeg.org >> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > Thanks > Steven > > > > > ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avformat/utils: Stream specifier enhancement
2018.04.04. 2:37 keltezéssel, Michael Niedermayer írta: On Sun, Apr 01, 2018 at 11:42:34PM +0200, Bodecs Bela wrote: Dear All, currently when specifying the program id you can only decide to select all stream of the specified program (e.g. p:103 will select all streams of program 103) or narrow the selection to a specific stream sub index (e.g. p:145:1 will select 2nd stream of program 145.) But you can not specify like all audio streams of program 145 or 3rd video stream of program 311. In some case, mainly working with multiprogram mpeg-ts containers as input, this feature would be handy. This patch makes it possible to narrow the stream selection among streams of the specified program by stream type and optionally its index. Handled types: a, v, s, d. Examples: p:601:a will select all audio streams of program 601, p:603:a:1 will select 2nd audio streams of program 603, p:604:v:0 will select first video stream of program 604. This syntax enhancement does not interfere in any way with current/exiting syntax or working command lines I think this is a good idea. Can you also add fate test(s) for this ? (can be in a seperate patch later of course) ok, I will try. bb thx [...] ___ 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
[FFmpeg-devel] [PATCH v2 11/11] avformat/dashenc: addition of segment index correction logic
From: Vishwanath Dixit The logic is applicable only when use_template is enabled and use_timeline is disabled. The logic monitors the flow of segment indexes. If a streams's segment index value is not at the expected real time position, then the logic corrects that index value. Typically this logic is needed in live streaming use cases. The network bandwidth fluctuations are common during long run streaming. Each fluctuation can cause the segment indexes fall behind the expected real time position. Without this logic, players will not be able to consume the content, even after encoder's network condition comes back to normal state. --- doc/muxers.texi | 11 +++ libavformat/dashenc.c | 31 ++- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/doc/muxers.texi b/doc/muxers.texi index 9e8b8a4..e5c9be1 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -271,6 +271,17 @@ To map all video (or audio) streams to an AdaptationSet, "v" (or "a") can be use When no assignment is defined, this defaults to an AdaptationSet for each stream. @item -timeout @var{timeout} Set timeout for socket I/O operations. Applicable only for HTTP output. +@item -index_correction @var{index_correction} +Enable (1) or Disable (0) segment index correction logic. Applicable only when +@var{use_template} is enabled and @var{use_timeline} is disabled. + +When enabled, the logic monitors the flow of segment indexes. If a streams's +segment index value is not at the expected real time position, then the logic +corrects that index value. + +Typically this logic is needed in live streaming use cases. The network bandwidth +fluctuations are common during long run streaming. Each fluctuation can cause +the segment indexes fall behind the expected real time position. @end table @anchor{framecrc} diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index ac05378..f0848c5 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -76,7 +76,7 @@ typedef struct OutputStream { int nb_segments, segments_size, segment_index; Segment **segments; int64_t first_pts, start_pts, max_pts; -int64_t last_dts; +int64_t last_dts, last_pts; int bit_rate; char codec_str[100]; @@ -121,6 +121,7 @@ typedef struct DASHContext { AVIOContext *m3u8_out; int streaming; int64_t timeout; +int index_correction; } DASHContext; static struct codec_string { @@ -1056,7 +1057,7 @@ static int dash_write_header(AVFormatContext *s) static int add_segment(OutputStream *os, const char *file, int64_t time, int duration, int64_t start_pos, int64_t range_length, - int64_t index_length) + int64_t index_length, int next_exp_index) { int err; Segment *seg; @@ -1084,6 +1085,12 @@ static int add_segment(OutputStream *os, const char *file, seg->index_length = index_length; os->segments[os->nb_segments++] = seg; os->segment_index++; +//correcting the segment index if it has fallen behind the expected value +if (os->segment_index < next_exp_index) { +av_log(NULL, AV_LOG_WARNING, "Correcting the segment index after file %s: current=%d corrected=%d\n", + file, os->segment_index, next_exp_index); +os->segment_index = next_exp_index; +} return 0; } @@ -1173,10 +1180,22 @@ static int dash_flush(AVFormatContext *s, int final, int stream) const char *proto = avio_find_protocol_name(s->url); int use_rename = proto && !strcmp(proto, "file"); -int cur_flush_segment_index = 0; -if (stream >= 0) +int cur_flush_segment_index = 0, next_exp_index = -1; +if (stream >= 0) { cur_flush_segment_index = c->streams[stream].segment_index; +//finding the next segment's expected index, based on the current pts value +if (c->use_template && !c->use_timeline && c->index_correction && +c->streams[stream].last_pts != AV_NOPTS_VALUE && +c->streams[stream].first_pts != AV_NOPTS_VALUE) { +int64_t pts_diff = av_rescale_q(c->streams[stream].last_pts - +c->streams[stream].first_pts, +s->streams[stream]->time_base, +AV_TIME_BASE_Q); +next_exp_index = (pts_diff / c->seg_duration) + 1; +} +} + for (i = 0; i < s->nb_streams; i++) { OutputStream *os = &c->streams[i]; AVStream *st = s->streams[i]; @@ -1236,7 +1255,7 @@ static int dash_flush(AVFormatContext *s, int final, int stream) if (bitrate >= 0) os->bit_rate = bitrate; } -add_segment(os, os->filename, os->start_pts, os->max_pts - os->start_pts, os->pos, range_length, index_length); +add_segment(os, os->filename, os->start_pts, os->max_pts - os->start_p
[FFmpeg-devel] [PATCH v2 09/11] avformat/dashenc: constructing MPD's bandwidth string locally
From: Vishwanath Dixit --- libavformat/dashenc.c | 20 +--- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 72431b7..31b0c92 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -78,7 +78,6 @@ typedef struct OutputStream { int64_t first_pts, start_pts, max_pts; int64_t last_dts; int bit_rate; -char bandwidth_str[64]; char codec_str[100]; int written_len; @@ -547,20 +546,25 @@ static int write_adaptation_set(AVFormatContext *s, AVIOContext *out, int as_ind for (i = 0; i < s->nb_streams; i++) { OutputStream *os = &c->streams[i]; +char bandwidth_str[64] = {'\0'}; if (os->as_idx - 1 != as_index) continue; +if (os->bit_rate > 0) +snprintf(bandwidth_str, sizeof(bandwidth_str), " bandwidth=\"%d\"", + os->bit_rate); + if (as->media_type == AVMEDIA_TYPE_VIDEO) { AVStream *st = s->streams[i]; avio_printf(out, "\t\t\tformat_name, os->codec_str, os->bandwidth_str, s->streams[i]->codecpar->width, s->streams[i]->codecpar->height); +i, os->format_name, os->codec_str, bandwidth_str, s->streams[i]->codecpar->width, s->streams[i]->codecpar->height); if (st->avg_frame_rate.num) avio_printf(out, " frameRate=\"%d/%d\"", st->avg_frame_rate.num, st->avg_frame_rate.den); avio_printf(out, ">\n"); } else { avio_printf(out, "\t\t\t\n", -i, os->format_name, os->codec_str, os->bandwidth_str, s->streams[i]->codecpar->sample_rate); +i, os->format_name, os->codec_str, bandwidth_str, s->streams[i]->codecpar->sample_rate); avio_printf(out, "\t\t\t\t\n", s->streams[i]->codecpar->channels); } @@ -914,10 +918,7 @@ static int dash_init(AVFormatContext *s) char filename[1024]; os->bit_rate = s->streams[i]->codecpar->bit_rate; -if (os->bit_rate) { -snprintf(os->bandwidth_str, sizeof(os->bandwidth_str), - " bandwidth=\"%d\"", os->bit_rate); -} else { +if (!os->bit_rate) { int level = s->strict_std_compliance >= FF_COMPLIANCE_STRICT ? AV_LOG_ERROR : AV_LOG_WARNING; av_log(s, level, "No bit rate set for stream %d\n", i); @@ -1232,11 +1233,8 @@ static int dash_flush(AVFormatContext *s, int final, int stream) int64_t bitrate = (int64_t) range_length * 8 * AV_TIME_BASE / av_rescale_q(os->max_pts - os->start_pts, st->time_base, AV_TIME_BASE_Q); -if (bitrate >= 0) { +if (bitrate >= 0) os->bit_rate = bitrate; -snprintf(os->bandwidth_str, sizeof(os->bandwidth_str), - " bandwidth=\"%d\"", os->bit_rate); -} } add_segment(os, os->filename, os->start_pts, os->max_pts - os->start_pts, os->pos, range_length, index_length); av_log(s, AV_LOG_VERBOSE, "Representation %d media segment %d written to: %s\n", i, os->segment_index, os->full_path); -- 1.9.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH v2 06/11] avformat/dashenc: addition of @availabilityTimeOffset in MPD
From: Vishwanath Dixit availability time of Nth segment = availabilityStartTime + (N*segment duration) - availabilityTimeOffset. This field helps to reduce the latency by about a segment duration in streaming mode. --- libavformat/dashenc.c | 14 +- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 9e7a374..5921ef7 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -85,6 +85,7 @@ typedef struct OutputStream { char filename[1024]; char full_path[1024]; char temp_path[1024]; +double availability_time_offset; } OutputStream; typedef struct DASHContext { @@ -344,8 +345,12 @@ static void output_segment_list(OutputStream *os, AVIOContext *out, AVFormatCont if (c->use_template) { int timescale = c->use_timeline ? os->ctx->streams[0]->time_base.den : AV_TIME_BASE; avio_printf(out, "\t\t\t\tuse_timeline) +if (!c->use_timeline) { avio_printf(out, "duration=\"%"PRId64"\" ", c->seg_duration); +if (c->streaming && os->availability_time_offset) +avio_printf(out, "availabilityTimeOffset=\"%.3f\" ", +os->availability_time_offset); +} avio_printf(out, "initialization=\"%s\" media=\"%s\" startNumber=\"%d\">\n", c->init_seg_name, c->media_seg_name, c->use_timeline ? start_number : 1); if (c->use_timeline) { int64_t cur_time = 0; @@ -1289,6 +1294,13 @@ static int dash_write_packet(AVFormatContext *s, AVPacket *pkt) format_date_now(c->availability_start_time, sizeof(c->availability_start_time)); +if (!os->availability_time_offset && pkt->duration) { +int64_t frame_duration = av_rescale_q(pkt->duration, st->time_base, + AV_TIME_BASE_Q); + os->availability_time_offset = ((double) c->seg_duration - + frame_duration) / AV_TIME_BASE; +} + if (c->use_template && !c->use_timeline) { elapsed_duration = pkt->pts - os->first_pts; seg_end_duration = (int64_t) os->segment_index * c->seg_duration; -- 1.9.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH v2 10/11] avformat/dashenc: addition of muxer overhead for @bandwidth param in MPD
From: Vishwanath Dixit --- libavformat/dashenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 31b0c92..ac05378 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -553,7 +553,7 @@ static int write_adaptation_set(AVFormatContext *s, AVIOContext *out, int as_ind if (os->bit_rate > 0) snprintf(bandwidth_str, sizeof(bandwidth_str), " bandwidth=\"%d\"", - os->bit_rate); + os->bit_rate + os->muxer_overhead); if (as->media_type == AVMEDIA_TYPE_VIDEO) { AVStream *st = s->streams[i]; -- 1.9.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH v2 07/11] avformat/dashenc: logic to compute muxer overhead
From: Vishwanath Dixit --- libavformat/dashenc.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 5921ef7..0fff91f 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -86,6 +86,8 @@ typedef struct OutputStream { char full_path[1024]; char temp_path[1024]; double availability_time_offset; +int total_pkt_size; +int muxer_overhead; } OutputStream; typedef struct DASHContext { @@ -1215,6 +1217,13 @@ static int dash_flush(AVFormatContext *s, int final, int stream) } } +if (!os->muxer_overhead) +os->muxer_overhead = ((int64_t) (range_length - os->total_pkt_size) * + 8 * AV_TIME_BASE) / + av_rescale_q(os->max_pts - os->start_pts, + st->time_base, AV_TIME_BASE_Q); +os->total_pkt_size = 0; + if (!os->bit_rate) { // calculate average bitrate of first segment int64_t bitrate = (int64_t) range_length * 8 * AV_TIME_BASE / av_rescale_q(os->max_pts - os->start_pts, @@ -1349,6 +1358,7 @@ static int dash_write_packet(AVFormatContext *s, AVPacket *pkt) else os->max_pts = FFMAX(os->max_pts, pkt->pts + pkt->duration); os->packets_written++; +os->total_pkt_size += pkt->size; if ((ret = ff_write_chained(os->ctx, 0, pkt, s, 0)) < 0) return ret; -- 1.9.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH v2 08/11] avformat/dashenc: addition of muxer overhead in master playlist's bandwidth
From: Vishwanath Dixit --- libavformat/dashenc.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 0fff91f..72431b7 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -825,20 +825,23 @@ static int write_manifest(AVFormatContext *s, int final) for (i = 0; i < s->nb_streams; i++) { char playlist_file[64]; AVStream *st = s->streams[i]; +OutputStream *os = &c->streams[i]; if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO) continue; get_hls_playlist_name(playlist_file, sizeof(playlist_file), NULL, i); ff_hls_write_audio_rendition(out, (char *)audio_group, playlist_file, i, is_default); -max_audio_bitrate = FFMAX(st->codecpar->bit_rate, max_audio_bitrate); +max_audio_bitrate = FFMAX(st->codecpar->bit_rate + + os->muxer_overhead, max_audio_bitrate); is_default = 0; } for (i = 0; i < s->nb_streams; i++) { char playlist_file[64]; AVStream *st = s->streams[i]; +OutputStream *os = &c->streams[i]; char *agroup = NULL; -int stream_bitrate = st->codecpar->bit_rate; +int stream_bitrate = st->codecpar->bit_rate + os->muxer_overhead; if ((st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) && max_audio_bitrate) { agroup = (char *)audio_group; stream_bitrate += max_audio_bitrate; -- 1.9.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH v2 04/11] avformat/dashenc: removed 'write_manifest' call from 'write_header'
From: Vishwanath Dixit Calling 'write_manifest' from 'write_header' was causing creation of first MPD with invalid values. Ex: zero @duration param value. Also, the manifest files (MPD or M3U8s) should be created when at-least one media frame is ready for consumption. --- libavformat/dashenc.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index e719409..1bac2c9 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -1042,9 +1042,6 @@ static int dash_write_header(AVFormatContext *s) if ((ret = avformat_write_header(os->ctx, NULL)) < 0) return ret; } -ret = write_manifest(s, 0); -if (!ret) -av_log(s, AV_LOG_VERBOSE, "Manifest written to: %s\n", s->url); return ret; } -- 1.9.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH v2 05/11] avformat/dashenc: setting @availabilityStartTime when the first frame is ready
From: Vishwanath Dixit @availabilityStartTime specifies the anchor for the computation of the earliest availability time (in UTC) for any Segment in the Media Presentation. As per this requirement, the @AvailabilityStartTime should be set to the wallclock time at which the first frame of the first segment begins encoding. But, it was getting set only when the first segment was completely ready. Making the required correction in this patch. This correction is mainly needed to reduce the latency in live streaming use cases. --- libavformat/dashenc.c | 7 --- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 1bac2c9..9e7a374 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -741,9 +741,6 @@ static int write_manifest(AVFormatContext *s, int final) update_period = 500; avio_printf(out, "\tminimumUpdatePeriod=\"PT%"PRId64"S\"\n", update_period); avio_printf(out, "\tsuggestedPresentationDelay=\"PT%"PRId64"S\"\n", c->last_duration / AV_TIME_BASE); -if (!c->availability_start_time[0] && s->nb_streams > 0 && c->streams[0].nb_segments > 0) { -format_date_now(c->availability_start_time, sizeof(c->availability_start_time)); -} if (c->availability_start_time[0]) avio_printf(out, "\tavailabilityStartTime=\"%s\"\n", c->availability_start_time); format_date_now(now_str, sizeof(now_str)); @@ -1288,6 +1285,10 @@ static int dash_write_packet(AVFormatContext *s, AVPacket *pkt) if (os->first_pts == AV_NOPTS_VALUE) os->first_pts = pkt->pts; +if (!c->availability_start_time[0]) +format_date_now(c->availability_start_time, +sizeof(c->availability_start_time)); + if (c->use_template && !c->use_timeline) { elapsed_duration = pkt->pts - os->first_pts; seg_end_duration = (int64_t) os->segment_index * c->seg_duration; -- 1.9.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH v2 02/11] avformat/dashenc: segmentation at the configured segment duration rate
From: Vishwanath Dixit When use_template is enabled and use_timeline is disabled, typically it is required to generate the segments at the configured segment duration rate on an average. This commit is particularly needed to handle the segmentation when video frame rates are fractional like 29.97 or 59.94 fps. --- doc/muxers.texi | 5 - libavformat/dashenc.c | 13 +++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/doc/muxers.texi b/doc/muxers.texi index a5358e3..9e8b8a4 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -228,7 +228,10 @@ ffmpeg -re -i -map 0 -map 0 -c:a libfdk_aac -c:v libx264 @item -min_seg_duration @var{microseconds} Set the segment length in microseconds (will be deprecated, use @var{seg_duration} instead). @item -seg_duration @var{duration} -Set the segment length in seconds (fractional value can be set). +Set the segment length in seconds (fractional value can be set). The value is +treated as average segment duration when @var{use_template} is enabled and +@var{use_timeline} is disabled and as minimum segment duration for all the other +use cases. @item -window_size @var{size} Set the maximum number of segments kept in the manifest. @item -extra_window_size @var{size} diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 8ef8627..54ccf30 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -1263,6 +1263,7 @@ static int dash_write_packet(AVFormatContext *s, AVPacket *pkt) DASHContext *c = s->priv_data; AVStream *st = s->streams[pkt->stream_index]; OutputStream *os = &c->streams[pkt->stream_index]; +int64_t seg_end_duration, elapsed_duration; int ret; ret = update_stream_extradata(s, os, st->codecpar); @@ -1290,10 +1291,18 @@ static int dash_write_packet(AVFormatContext *s, AVPacket *pkt) if (os->first_pts == AV_NOPTS_VALUE) os->first_pts = pkt->pts; +if (c->use_template && !c->use_timeline) { +elapsed_duration = pkt->pts - os->first_pts; +seg_end_duration = (int64_t) os->segment_index * c->seg_duration; +} else { +elapsed_duration = pkt->pts - os->start_pts; +seg_end_duration = c->seg_duration; +} + if ((!c->has_video || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) && pkt->flags & AV_PKT_FLAG_KEY && os->packets_written && -av_compare_ts(pkt->pts - os->start_pts, st->time_base, - c->seg_duration, AV_TIME_BASE_Q) >= 0) { +av_compare_ts(elapsed_duration, st->time_base, + seg_end_duration, AV_TIME_BASE_Q) >= 0) { int64_t prev_duration = c->last_duration; c->last_duration = av_rescale_q(pkt->pts - os->start_pts, -- 1.9.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH v2 03/11] avformat/dashenc: writing average segment duration for @duration in template mode
From: Vishwanath Dixit --- libavformat/dashenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 54ccf30..e719409 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -345,7 +345,7 @@ static void output_segment_list(OutputStream *os, AVIOContext *out, AVFormatCont int timescale = c->use_timeline ? os->ctx->streams[0]->time_base.den : AV_TIME_BASE; avio_printf(out, "\t\t\t\tuse_timeline) -avio_printf(out, "duration=\"%"PRId64"\" ", c->last_duration); +avio_printf(out, "duration=\"%"PRId64"\" ", c->seg_duration); avio_printf(out, "initialization=\"%s\" media=\"%s\" startNumber=\"%d\">\n", c->init_seg_name, c->media_seg_name, c->use_timeline ? start_number : 1); if (c->use_timeline) { int64_t cur_time = 0; -- 1.9.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH v2 01/11] avformat/dashenc: replacing 'min_seg_duration' with 'seg_duration'
From: Vishwanath Dixit --- doc/muxers.texi | 4 +++- libavformat/dashenc.c | 17 - libavformat/version.h | 2 +- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/doc/muxers.texi b/doc/muxers.texi index cb75c26..a5358e3 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -226,7 +226,9 @@ ffmpeg -re -i -map 0 -map 0 -c:a libfdk_aac -c:v libx264 @table @option @item -min_seg_duration @var{microseconds} -Set the segment length in microseconds. +Set the segment length in microseconds (will be deprecated, use @var{seg_duration} instead). +@item -seg_duration @var{duration} +Set the segment length in seconds (fractional value can be set). @item -window_size @var{size} Set the maximum number of segments kept in the manifest. @item -extra_window_size @var{size} diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index bdf8c8d..8ef8627 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -95,6 +95,7 @@ typedef struct DASHContext { int window_size; int extra_window_size; int min_seg_duration; +int64_t seg_duration; int remove_at_exit; int use_template; int use_timeline; @@ -871,6 +872,11 @@ static int dash_init(AVFormatContext *s) if (c->single_file) c->use_template = 0; +if (c->min_seg_duration != 500) { +av_log(s, AV_LOG_WARNING, "The min_seg_duration option is deprecated and will be removed. Please use the -seg_duration\n"); +c->seg_duration = c->min_seg_duration; +} + av_strlcpy(c->dirname, s->url, sizeof(c->dirname)); ptr = strrchr(c->dirname, '/'); if (ptr) { @@ -974,7 +980,7 @@ static int dash_init(AVFormatContext *s) else av_dict_set(&opts, "movflags", "frag_custom+dash+delay_moov", 0); } else { -av_dict_set_int(&opts, "cluster_time_limit", c->min_seg_duration / 1000, 0); +av_dict_set_int(&opts, "cluster_time_limit", c->seg_duration / 1000, 0); av_dict_set_int(&opts, "cluster_size_limit", 5 * 1024 * 1024, 0); // set a large cluster size limit av_dict_set_int(&opts, "dash", 1, 0); av_dict_set_int(&opts, "dash_track_number", i + 1, 0); @@ -1020,8 +1026,8 @@ static int dash_init(AVFormatContext *s) os->segment_index = 1; } -if (!c->has_video && c->min_seg_duration <= 0) { -av_log(s, AV_LOG_WARNING, "no video stream and no min seg duration set\n"); +if (!c->has_video && c->seg_duration <= 0) { +av_log(s, AV_LOG_WARNING, "no video stream and no seg duration set\n"); return AVERROR(EINVAL); } return 0; @@ -1287,7 +1293,7 @@ static int dash_write_packet(AVFormatContext *s, AVPacket *pkt) if ((!c->has_video || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) && pkt->flags & AV_PKT_FLAG_KEY && os->packets_written && av_compare_ts(pkt->pts - os->start_pts, st->time_base, - c->min_seg_duration, AV_TIME_BASE_Q) >= 0) { + c->seg_duration, AV_TIME_BASE_Q) >= 0) { int64_t prev_duration = c->last_duration; c->last_duration = av_rescale_q(pkt->pts - os->start_pts, @@ -1427,7 +1433,8 @@ static const AVOption options[] = { { "adaptation_sets", "Adaptation sets. Syntax: id=0,streams=0,1,2 id=1,streams=3,4 and so on", OFFSET(adaptation_sets), AV_OPT_TYPE_STRING, { 0 }, 0, 0, AV_OPT_FLAG_ENCODING_PARAM }, { "window_size", "number of segments kept in the manifest", OFFSET(window_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, E }, { "extra_window_size", "number of segments kept outside of the manifest before removing from disk", OFFSET(extra_window_size), AV_OPT_TYPE_INT, { .i64 = 5 }, 0, INT_MAX, E }, -{ "min_seg_duration", "minimum segment duration (in microseconds)", OFFSET(min_seg_duration), AV_OPT_TYPE_INT, { .i64 = 500 }, 0, INT_MAX, E }, +{ "min_seg_duration", "minimum segment duration (in microseconds) (will be deprecated)", OFFSET(min_seg_duration), AV_OPT_TYPE_INT, { .i64 = 500 }, 0, INT_MAX, E }, +{ "seg_duration", "segment duration (in seconds, fractional value can be set)", OFFSET(seg_duration), AV_OPT_TYPE_DURATION, { .i64 = 500 }, 0, INT_MAX, E }, { "remove_at_exit", "remove all segments when finished", OFFSET(remove_at_exit), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E }, { "use_template", "Use SegmentTemplate instead of SegmentList", OFFSET(use_template), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, E }, { "use_timeline", "Use SegmentTimeline in SegmentTemplate", OFFSET(use_timeline), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, E }, diff --git a/libavformat/version.h b/libavformat/version.h index e28a9e7..aca592b 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -33,7 +33,7 @@ // Also please add any ticket numbers that you believe might be affected here #define LIBAVFORMAT_VERSION_MAJOR 58 #define LIBAVFORMAT_VERSION_MINOR 10 -#defi
Re: [FFmpeg-devel] [PATCH] libavformat/aac: Parse all ID3 tags present between ADTS frames
On 2018-04-04 03:42, James Almer wrote: On 4/3/2018 10:40 PM, Carl Eugen Hoyos wrote: 2018-04-04 3:38 GMT+02:00, James Almer : On 4/3/2018 10:33 PM, Carl Eugen Hoyos wrote: 2018-04-03 7:58 GMT+02:00, Mattias Amnefelt : Yes, my feeling was also that it's better to handle this when possible. You are of course correct that the two tags needs to be inbetween frames. Sorry about that, I stripped the sample down too much. I updated with a sample which has two frames. This new sample fails the test without the patch. +fate-adts-id3v2-two-tags-demux: CMD = framecrc -f aac -i $(TARGET_SAMPLES)/aac/id3v2_two_tags.aac -c:a copy The "-f aac" looks like a bad idea to me. It's also true for the tests above, but that's still not reason to add more. Please avoid top-posting here, Carl Eugen At least in one of them it was added because the sample had too few frames and probing was detecting it with a score of 1, which seemed too fragile. I believe that it is good to have a sample that is detected with a small score as part of fate. Carl Eugen When i asked it was suggested to just force the demuxer. I have no opinion one way or another, so feel free to change it. I have to admit I just copy-n-pasted the test above. I just double-checked and all the id3 tag tests pass without -f aac now. I'm not sure if anything has changed since the test was added or not. Do you want a patch which removes it for all of them? /mattiasa ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel