From 35c858066840352d6d43385bbc728467c5150974 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 21 May 2016 11:37:33 +0200 Subject: [PATCH 01/37] avconv: stop using AVStream.codec It is now only used by the av_parser_change() call during streamcopy, so allocate a special AVCodecContext instance for this case. This instance should go away when the new parser API is finished. Signed-off-by: Diego Biurrun --- avconv.c | 21 ++++++++------------- avconv.h | 1 + 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/avconv.c b/avconv.c index 74459ab6ba..e48f03162c 100644 --- a/avconv.c +++ b/avconv.c @@ -184,6 +184,7 @@ static void avconv_cleanup(int ret) av_frame_free(&ost->filtered_frame); av_parser_close(ost->parser); + avcodec_free_context(&ost->parser_avctx); av_freep(&ost->forced_keyframes); av_freep(&ost->avfilter); @@ -1101,7 +1102,7 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p && ost->enc_ctx->codec_id != AV_CODEC_ID_MPEG2VIDEO && ost->enc_ctx->codec_id != AV_CODEC_ID_VC1 ) { - if (av_parser_change(ost->parser, ost->st->codec, + if (av_parser_change(ost->parser, ost->parser_avctx, &opkt.data, &opkt.size, pkt->data, pkt->size, pkt->flags & AV_PKT_FLAG_KEY)) { @@ -1709,14 +1710,6 @@ static int init_output_stream(OutputStream *ost, char *error, int error_len) "Error initializing the output stream codec context.\n"); exit_program(1); } - /* - * FIXME: this is only so that the bitstream filters and parsers (that still - * work with a codec context) get the parameter values. - * This should go away with the new BSF/parser API. - */ - ret = avcodec_copy_context(ost->st->codec, ost->enc_ctx); - if (ret < 0) - return ret; if (ost->enc_ctx->nb_coded_side_data) { int i; @@ -1747,11 +1740,10 @@ static int init_output_stream(OutputStream *ost, char *error, int error_len) return ret; /* - * FIXME: this is only so that the bitstream filters and parsers (that still - * work with a codec context) get the parameter values. - * This should go away with the new BSF/parser API. + * FIXME: will the codec context used by the parser during streamcopy + * This should go away with the new parser API. */ - ret = avcodec_parameters_to_context(ost->st->codec, ost->st->codecpar); + ret = avcodec_parameters_to_context(ost->parser_avctx, ost->st->codecpar); if (ret < 0) return ret; } @@ -1913,6 +1905,9 @@ static int transcode_init(void) } ost->parser = av_parser_init(par_dst->codec_id); + ost->parser_avctx = avcodec_alloc_context3(NULL); + if (!ost->parser_avctx) + return AVERROR(ENOMEM); switch (par_dst->codec_type) { case AVMEDIA_TYPE_AUDIO: diff --git a/avconv.h b/avconv.h index 05abae6865..84fabf6371 100644 --- a/avconv.h +++ b/avconv.h @@ -372,6 +372,7 @@ typedef struct OutputStream { enum AVPixelFormat pix_fmts[2]; AVCodecParserContext *parser; + AVCodecContext *parser_avctx; /* stats */ // combined size of all the packets written From e2a3df1a464091075040a81ffc419fa21a8a5fd8 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 21 May 2016 13:49:46 +0200 Subject: [PATCH 02/37] avconv: Use more precise deprecation ifdefs This fixes compilation with the libavcodec version bumped to 58. --- avconv.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/avconv.c b/avconv.c index e48f03162c..d8631036a1 100644 --- a/avconv.c +++ b/avconv.c @@ -570,7 +570,7 @@ error: exit_program(1); } -#if FF_API_CODED_FRAME +#if FF_API_CODED_FRAME && FF_API_ERROR_FRAME static double psnr(double d) { return -10.0 * log(d) / log(10.0); @@ -598,7 +598,7 @@ static void do_video_stats(OutputStream *ost, int frame_size) fprintf(vstats_file, "frame= %5d q= %2.1f ", frame_number, ost->quality / (float)FF_QP2LAMBDA); -#if FF_API_CODED_FRAME +#if FF_API_CODED_FRAME && FF_API_ERROR_FRAME FF_DISABLE_DEPRECATION_WARNINGS if (enc->flags & AV_CODEC_FLAG_PSNR) fprintf(vstats_file, "PSNR= %6.2f ", psnr(enc->coded_frame->error[0] / (enc->width * enc->height * 255.0 * 255.0))); @@ -913,7 +913,7 @@ static void print_report(int is_last_report, int64_t timer_start) snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%X", (int)lrintf(log2(qp_histogram[j] + 1))); } -#if FF_API_CODED_FRAME +#if FF_API_CODED_FRAME && FF_API_ERROR_FRAME FF_DISABLE_DEPRECATION_WARNINGS if (enc->flags & AV_CODEC_FLAG_PSNR) { int j; From e45a638f50cc1dbeb87b9792e68f57e77fc0c3b5 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 21 May 2016 13:41:19 +0200 Subject: [PATCH 03/37] dump: Drop unused variable --- libavformat/dump.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libavformat/dump.c b/libavformat/dump.c index bef0e76b80..3b50f5d944 100644 --- a/libavformat/dump.c +++ b/libavformat/dump.c @@ -233,7 +233,6 @@ static void dump_replaygain(void *ctx, AVPacketSideData *sd) static void dump_stereo3d(void *ctx, AVPacketSideData *sd) { AVStereo3D *stereo; - const char *name; if (sd->size < sizeof(*stereo)) { av_log(ctx, AV_LOG_INFO, "invalid data"); From 52567e8198669a1e7493c75771613f87a90466c3 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 21 May 2016 13:31:24 +0200 Subject: [PATCH 04/37] get_bits: Drop some TRACE-level debug code It will not be provided by the new bit reader anyway. --- libavcodec/get_bits.h | 64 ----------------------------------------- libavcodec/golomb.h | 6 ---- libavcodec/h264_cavlc.c | 4 --- 3 files changed, 74 deletions(-) diff --git a/libavcodec/get_bits.h b/libavcodec/get_bits.h index 66374f523d..b225c132bb 100644 --- a/libavcodec/get_bits.h +++ b/libavcodec/get_bits.h @@ -528,68 +528,4 @@ static inline int get_bits_left(GetBitContext *gb) return gb->size_in_bits - get_bits_count(gb); } -//#define TRACE - -#ifdef TRACE -static inline void print_bin(int bits, int n) -{ - int i; - - for (i = n - 1; i >= 0; i--) - av_log(NULL, AV_LOG_DEBUG, "%d", (bits >> i) & 1); - for (i = n; i < 24; i++) - av_log(NULL, AV_LOG_DEBUG, " "); -} - -static inline int get_bits_trace(GetBitContext *s, int n, const char *file, - const char *func, int line) -{ - int r = get_bits(s, n); - - print_bin(r, n); - av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d bit @%5d in %s %s:%d\n", - r, n, r, get_bits_count(s) - n, file, func, line); - - return r; -} - -static inline int get_vlc_trace(GetBitContext *s, VLC_TYPE (*table)[2], - int bits, int max_depth, const char *file, - const char *func, int line) -{ - int show = show_bits(s, 24); - int pos = get_bits_count(s); - int r = get_vlc2(s, table, bits, max_depth); - int len = get_bits_count(s) - pos; - int bits2 = show >> (24 - len); - - print_bin(bits2, len); - - av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d vlc @%5d in %s %s:%d\n", - bits2, len, r, pos, file, func, line); - - return r; -} - -static inline int get_xbits_trace(GetBitContext *s, int n, const char *file, - const char *func, int line) -{ - int show = show_bits(s, n); - int r = get_xbits(s, n); - - print_bin(show, n); - av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d xbt @%5d in %s %s:%d\n", - show, n, r, get_bits_count(s) - n, file, func, line); - - return r; -} - -#define get_bits(s, n) get_bits_trace(s , n, __FILE__, __PRETTY_FUNCTION__, __LINE__) -#define get_bits1(s) get_bits_trace(s, 1, __FILE__, __PRETTY_FUNCTION__, __LINE__) -#define get_xbits(s, n) get_xbits_trace(s, n, __FILE__, __PRETTY_FUNCTION__, __LINE__) - -#define get_vlc(s, vlc) get_vlc_trace(s, (vlc)->table, (vlc)->bits, 3, __FILE__, __PRETTY_FUNCTION__, __LINE__) -#define get_vlc2(s, tab, bits, max) get_vlc_trace(s, tab, bits, max, __FILE__, __PRETTY_FUNCTION__, __LINE__) -#endif - #endif /* AVCODEC_GET_BITS_H */ diff --git a/libavcodec/golomb.h b/libavcodec/golomb.h index 22a87c64e1..398fe3b30a 100644 --- a/libavcodec/golomb.h +++ b/libavcodec/golomb.h @@ -413,8 +413,6 @@ static inline int get_ue(GetBitContext *s, const char *file, const char *func, int len = get_bits_count(s) - pos; int bits = show >> (24 - len); - print_bin(bits, len); - av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d ue @%5d in %s %s:%d\n", bits, len, i, pos, file, func, line); @@ -430,8 +428,6 @@ static inline int get_se(GetBitContext *s, const char *file, const char *func, int len = get_bits_count(s) - pos; int bits = show >> (24 - len); - print_bin(bits, len); - av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d se @%5d in %s %s:%d\n", bits, len, i, pos, file, func, line); @@ -447,8 +443,6 @@ static inline int get_te(GetBitContext *s, int r, char *file, const char *func, int len = get_bits_count(s) - pos; int bits = show >> (24 - len); - print_bin(bits, len); - av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d te @%5d in %s %s:%d\n", bits, len, i, pos, file, func, line); diff --git a/libavcodec/h264_cavlc.c b/libavcodec/h264_cavlc.c index 1a80f76d96..5d80243968 100644 --- a/libavcodec/h264_cavlc.c +++ b/libavcodec/h264_cavlc.c @@ -421,10 +421,6 @@ static inline int get_level_prefix(GetBitContext *gb){ buf=GET_CACHE(re, gb); log= 32 - av_log2(buf); -#ifdef TRACE - print_bin(buf>>(32-log), log); - av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d lpr @%5d in %s get_level_prefix\n", buf>>(32-log), log, log-1, get_bits_count(gb), __FILE__); -#endif LAST_SKIP_BITS(re, gb, log); CLOSE_READER(re, gb); From 74b1bf632f125a795e66e5fd0a060b9c7c55b7a3 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Tue, 19 Apr 2016 06:35:53 +0200 Subject: [PATCH 05/37] mp3: Make the extrasize explicit Initialize the bit buffer with the correct size (amount of bits that will be read) instead of relying on the bitstream reader overreading the correct values. Signed-off-by: Luca Barbato Signed-off-by: Diego Biurrun --- libavcodec/mpegaudiodec_template.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/libavcodec/mpegaudiodec_template.c b/libavcodec/mpegaudiodec_template.c index 2518387162..9bfba6f221 100644 --- a/libavcodec/mpegaudiodec_template.c +++ b/libavcodec/mpegaudiodec_template.c @@ -70,6 +70,7 @@ typedef struct MPADecodeContext { MPA_DECODE_HEADER uint8_t last_buf[LAST_BUF_SIZE]; int last_buf_size; + int extrasize; /* next header (used in free format parsing) */ uint32_t free_format_next_header; GetBitContext gb; @@ -798,9 +799,10 @@ static void exponents_from_scale_factors(MPADecodeContext *s, GranuleDef *g, static void switch_buffer(MPADecodeContext *s, int *pos, int *end_pos, int *end_pos2) { - if (s->in_gb.buffer && *pos >= s->gb.size_in_bits) { + if (s->in_gb.buffer && *pos >= s->gb.size_in_bits - s->extrasize * 8) { s->gb = s->in_gb; s->in_gb.buffer = NULL; + s->extrasize = 0; assert((get_bits_count(&s->gb) & 7) == 0); skip_bits_long(&s->gb, *pos - *end_pos); *end_pos2 = @@ -832,7 +834,7 @@ static int huffman_decode(MPADecodeContext *s, GranuleDef *g, int i; int last_pos, bits_left; VLC *vlc; - int end_pos = FFMIN(end_pos2, s->gb.size_in_bits); + int end_pos = FFMIN(end_pos2, s->gb.size_in_bits - s->extrasize * 8); /* low frequencies (called big values) */ s_index = 0; @@ -1354,19 +1356,16 @@ static int mp_decode_layer3(MPADecodeContext *s) if (!s->adu_mode) { int skip; const uint8_t *ptr = s->gb.buffer + (get_bits_count(&s->gb)>>3); - int extrasize = av_clip(get_bits_left(&s->gb) >> 3, 0, - FFMAX(0, LAST_BUF_SIZE - s->last_buf_size)); + s->extrasize = av_clip((get_bits_left(&s->gb) >> 3) - s->extrasize, 0, + FFMAX(0, LAST_BUF_SIZE - s->last_buf_size)); assert((get_bits_count(&s->gb) & 7) == 0); /* now we get bits from the main_data_begin offset */ ff_dlog(s->avctx, "seekback:%d, lastbuf:%d\n", main_data_begin, s->last_buf_size); - memcpy(s->last_buf + s->last_buf_size, ptr, extrasize); + memcpy(s->last_buf + s->last_buf_size, ptr, s->extrasize); s->in_gb = s->gb; - init_get_bits(&s->gb, s->last_buf, s->last_buf_size*8); -#if !UNCHECKED_BITSTREAM_READER - s->gb.size_in_bits_plus8 += extrasize * 8; -#endif + init_get_bits(&s->gb, s->last_buf, (s->last_buf_size + s->extrasize) * 8); s->last_buf_size <<= 3; for (gr = 0; gr < nb_granules && (s->last_buf_size >> 3) < main_data_begin; gr++) { for (ch = 0; ch < s->nb_channels; ch++) { @@ -1377,15 +1376,17 @@ static int mp_decode_layer3(MPADecodeContext *s) } } skip = s->last_buf_size - 8 * main_data_begin; - if (skip >= s->gb.size_in_bits && s->in_gb.buffer) { - skip_bits_long(&s->in_gb, skip - s->gb.size_in_bits); + if (skip >= s->gb.size_in_bits - s->extrasize * 8 && s->in_gb.buffer) { + skip_bits_long(&s->in_gb, skip - s->gb.size_in_bits + s->extrasize * 8); s->gb = s->in_gb; s->in_gb.buffer = NULL; + s->extrasize = 0; } else { skip_bits_long(&s->gb, skip); } } else { gr = 0; + s->extrasize = 0; } for (; gr < nb_granules; gr++) { @@ -1553,7 +1554,7 @@ static int mp_decode_frame(MPADecodeContext *s, OUT_INT **samples, s->last_buf_size=0; if (s->in_gb.buffer) { align_get_bits(&s->gb); - i = get_bits_left(&s->gb)>>3; + i = (get_bits_left(&s->gb) >> 3) - s->extrasize; if (i >= 0 && i <= BACKSTEP_SIZE) { memmove(s->last_buf, s->gb.buffer + (get_bits_count(&s->gb)>>3), i); s->last_buf_size=i; @@ -1561,12 +1562,12 @@ static int mp_decode_frame(MPADecodeContext *s, OUT_INT **samples, av_log(s->avctx, AV_LOG_ERROR, "invalid old backstep %d\n", i); s->gb = s->in_gb; s->in_gb.buffer = NULL; + s->extrasize = 0; } align_get_bits(&s->gb); assert((get_bits_count(&s->gb) & 7) == 0); - i = get_bits_left(&s->gb) >> 3; - + i = (get_bits_left(&s->gb) >> 3) - s->extrasize; if (i < 0 || i > BACKSTEP_SIZE || nb_frames < 0) { if (i < 0) av_log(s->avctx, AV_LOG_ERROR, "invalid new backstep %d\n", i); From 14634429b915333f3612eaf41db3954222dc4aaf Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 21 May 2016 11:41:37 +0200 Subject: [PATCH 06/37] lavf: update muxing doxy Describe the new AVCodecParameters API. --- libavformat/avformat.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavformat/avformat.h b/libavformat/avformat.h index fbdfba4fb1..65c3d90d4b 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -191,15 +191,15 @@ * avio_open2() or a custom one. * - Unless the format is of the AVFMT_NOSTREAMS type, at least one stream must * be created with the avformat_new_stream() function. The caller should fill - * the @ref AVStream.codec "stream codec context" information, such as the - * codec @ref AVCodecContext.codec_type "type", @ref AVCodecContext.codec_id + * the @ref AVStream.codecpar "stream codec parameters" information, such as the + * codec @ref AVCodecParameters.codec_type "type", @ref AVCodecParameters.codec_id * "id" and other parameters (e.g. width / height, the pixel or sample format, * etc.) as known. The @ref AVStream.time_base "stream timebase" should * be set to the timebase that the caller desires to use for this stream (note * that the timebase actually used by the muxer can be different, as will be * described later). * - It is advised to manually initialize only the relevant fields in - * AVCodecContext, rather than using @ref avcodec_copy_context() during + * AVCodecParameters, rather than using @ref avcodec_parameters_copy() during * remuxing: there is no guarantee that the codec context values remain valid * for both input and output format contexts. * - The caller may fill in additional information, such as @ref From 5f30ac27795f9f98043e8582ccaad8813104adc4 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 21 May 2016 11:46:44 +0200 Subject: [PATCH 07/37] lavc: deprecate avcodec_copy_context() Since AVCodecContext contains a lot of complex state, copying a codec context is not a well-defined operation. The purpose for which it is typically used (which is well-defined) is copying the stream parameters from one codec context to another. That is now possible with through the AVCodecParameters API. Therefore, there is no reason for avcodec_copy_context() to exist. --- libavcodec/avcodec.h | 9 +++++++++ libavcodec/options.c | 2 ++ libavcodec/version.h | 3 +++ 3 files changed, 14 insertions(+) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index bb545651ae..639ecf343e 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -3648,6 +3648,7 @@ int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec); */ const AVClass *avcodec_get_class(void); +#if FF_API_COPY_CONTEXT /** * Copy the settings of the source AVCodecContext into the destination * AVCodecContext. The resulting destination codec context will be @@ -3658,8 +3659,16 @@ const AVClass *avcodec_get_class(void); * avcodec_alloc_context3(), but otherwise uninitialized * @param src source codec context * @return AVERROR() on error (e.g. memory allocation error), 0 on success + * + * @deprecated The semantics of this function are ill-defined and it should not + * be used. If you need to transfer the stream parameters from one codec context + * to another, use an intermediate AVCodecParameters instance and the + * avcodec_parameters_from_context() / avcodec_parameters_to_context() + * functions. */ +attribute_deprecated int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src); +#endif /** * Allocate a new AVCodecParameters and set its fields to default values diff --git a/libavcodec/options.c b/libavcodec/options.c index 49c8aea030..50bacd3df8 100644 --- a/libavcodec/options.c +++ b/libavcodec/options.c @@ -155,6 +155,7 @@ void avcodec_free_context(AVCodecContext **pavctx) av_freep(pavctx); } +#if FF_API_COPY_CONTEXT int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src) { const AVCodec *orig_codec = dest->codec; @@ -225,6 +226,7 @@ fail: #endif return AVERROR(ENOMEM); } +#endif const AVClass *avcodec_get_class(void) { diff --git a/libavcodec/version.h b/libavcodec/version.h index db3f33a6e6..57006c9fc8 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -200,5 +200,8 @@ #ifndef FF_API_OLD_BSF #define FF_API_OLD_BSF (LIBAVCODEC_VERSION_MAJOR < 59) #endif +#ifndef FF_API_COPY_CONTEXT +#define FF_API_COPY_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 59) +#endif #endif /* AVCODEC_VERSION_H */ From 04fc8e24a091ed1d77d7a3c0cbcfe60baec19a9f Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 21 May 2016 11:57:28 +0200 Subject: [PATCH 08/37] lavc: deprecate avcodec_get_context_defaults3() This function is supposed to "reset" a codec context to a clean state so that it can be opened again. The only reason it exists is to allow using AVStream.codec as a decoding context (after it was already opened/used/closed by avformat_find_stream_info()). Since that behaviour is now deprecated, there is no reason for this function to exist anymore. --- libavcodec/avcodec.h | 23 +++++++++-------------- libavcodec/options.c | 11 +++++++++-- libavcodec/version.h | 3 +++ 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 639ecf343e..24cf39f324 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -3619,7 +3619,6 @@ void avcodec_register_all(void); * important mainly for encoders, e.g. libx264). * * @return An AVCodecContext filled with default values or NULL on failure. - * @see avcodec_get_context_defaults */ AVCodecContext *avcodec_alloc_context3(const AVCodec *codec); @@ -3629,16 +3628,14 @@ AVCodecContext *avcodec_alloc_context3(const AVCodec *codec); */ void avcodec_free_context(AVCodecContext **avctx); +#if FF_API_GET_CONTEXT_DEFAULTS /** - * Set the fields of the given AVCodecContext to default values corresponding - * to the given codec (defaults may be codec-dependent). - * - * Do not call this function if a non-NULL codec has been passed - * to avcodec_alloc_context3() that allocated this AVCodecContext. - * If codec is non-NULL, it is illegal to call avcodec_open2() with a - * different codec on this AVCodecContext. + * @deprecated This function should not be used, as closing and opening a codec + * context multiple time is not supported. A new codec context should be + * allocated for each new use. */ int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec); +#endif /** * Get the AVClass for AVCodecContext. It can be used in combination with @@ -3741,9 +3738,8 @@ int avcodec_parameters_to_context(AVCodecContext *codec, * @param avctx The context to initialize. * @param codec The codec to open this context for. If a non-NULL codec has been * previously passed to avcodec_alloc_context3() or - * avcodec_get_context_defaults3() for this context, then this - * parameter MUST be either NULL or equal to the previously passed - * codec. + * for this context, then this parameter MUST be either NULL or + * equal to the previously passed codec. * @param options A dictionary filled with AVCodecContext and codec-private options. * On return this object will be filled with options that were not found. * @@ -3758,9 +3754,8 @@ int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **op * (but not the AVCodecContext itself). * * Calling this function on an AVCodecContext that hasn't been opened will free - * the codec-specific data allocated in avcodec_alloc_context3() / - * avcodec_get_context_defaults3() with a non-NULL codec. Subsequent calls will - * do nothing. + * the codec-specific data allocated in avcodec_alloc_context3() with a non-NULL + * codec. Subsequent calls will do nothing. */ int avcodec_close(AVCodecContext *avctx); diff --git a/libavcodec/options.c b/libavcodec/options.c index 50bacd3df8..117ae5e445 100644 --- a/libavcodec/options.c +++ b/libavcodec/options.c @@ -80,7 +80,7 @@ static const AVClass av_codec_context_class = { .child_class_next = codec_child_class_next, }; -int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec) +static int init_context_defaults(AVCodecContext *s, const AVCodec *codec) { memset(s, 0, sizeof(AVCodecContext)); @@ -125,6 +125,13 @@ int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec) return 0; } +#if FF_API_GET_CONTEXT_DEFAULTS +int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec) +{ + return init_context_defaults(s, codec); +} +#endif + AVCodecContext *avcodec_alloc_context3(const AVCodec *codec) { AVCodecContext *avctx= av_malloc(sizeof(AVCodecContext)); @@ -132,7 +139,7 @@ AVCodecContext *avcodec_alloc_context3(const AVCodec *codec) if (!avctx) return NULL; - if(avcodec_get_context_defaults3(avctx, codec) < 0){ + if (init_context_defaults(avctx, codec) < 0) { av_free(avctx); return NULL; } diff --git a/libavcodec/version.h b/libavcodec/version.h index 57006c9fc8..ef5b7420eb 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -203,5 +203,8 @@ #ifndef FF_API_COPY_CONTEXT #define FF_API_COPY_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 59) #endif +#ifndef FF_API_GET_CONTEXT_DEFAULTS +#define FF_API_GET_CONTEXT_DEFAULTS (LIBAVCODEC_VERSION_MAJOR < 59) +#endif #endif /* AVCODEC_VERSION_H */ From 2ef6dab0a79a9852a92ed80b07f9e32a37530d9e Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 21 May 2016 12:05:38 +0200 Subject: [PATCH 09/37] lavc: document that avcodec_close() should not be used We cannot deprecate it until the new parser API is in place, because of the way libavformat works. But the majority of the users can already simply replace it with avcodec_free_context(), which will simplify the transition once it is finally deprecated. --- libavcodec/avcodec.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 24cf39f324..dc6649af54 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -3756,6 +3756,11 @@ int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **op * Calling this function on an AVCodecContext that hasn't been opened will free * the codec-specific data allocated in avcodec_alloc_context3() with a non-NULL * codec. Subsequent calls will do nothing. + * + * @note Do not use this function. Use avcodec_free_context() to destroy a + * codec context (either open or closed). Opening and closing a codec context + * multiple times is not supported anymore -- use multiple codec contexts + * instead. */ int avcodec_close(AVCodecContext *avctx); From ac84e618df4765ba751327497994066d0931e6a8 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 22 May 2016 10:46:19 +0200 Subject: [PATCH 10/37] avfiltergraph: check the query_formats() return value --- libavfilter/avfiltergraph.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c index 6832664530..5053e3c37a 100644 --- a/libavfilter/avfiltergraph.c +++ b/libavfilter/avfiltergraph.c @@ -271,9 +271,15 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) /* ask all the sub-filters for their supported media formats */ for (i = 0; i < graph->nb_filters; i++) { if (graph->filters[i]->filter->query_formats) - graph->filters[i]->filter->query_formats(graph->filters[i]); + ret = graph->filters[i]->filter->query_formats(graph->filters[i]); else - ff_default_query_formats(graph->filters[i]); + ret = ff_default_query_formats(graph->filters[i]); + if (ret < 0) { + av_log(log_ctx, AV_LOG_ERROR, + "Error querying formats for the filter %s (%s)\n", + graph->filters[i]->name, graph->filters[i]->filter->name); + return ret; + } } /* go through and merge as many format lists as possible */ From ad61da054bd8c74a5d5b38d80846228fc6147108 Mon Sep 17 00:00:00 2001 From: Francois Cartegnie Date: Mon, 23 May 2016 14:12:15 +0200 Subject: [PATCH 11/37] jpeg2000: Fix profile define values Signed-off-by: Diego Biurrun --- libavcodec/avcodec.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index dc6649af54..f33b7e5ac9 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -2934,9 +2934,9 @@ typedef struct AVCodecContext { #define FF_PROFILE_MPEG4_SIMPLE_STUDIO 14 #define FF_PROFILE_MPEG4_ADVANCED_SIMPLE 15 -#define FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_0 0 -#define FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_1 1 -#define FF_PROFILE_JPEG2000_CSTREAM_NO_RESTRICTION 2 +#define FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_0 1 +#define FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_1 2 +#define FF_PROFILE_JPEG2000_CSTREAM_NO_RESTRICTION 32768 #define FF_PROFILE_JPEG2000_DCINEMA_2K 3 #define FF_PROFILE_JPEG2000_DCINEMA_4K 4 From e47b8bbf0b54599d44b9330eb4d68cdde4f6d298 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 24 May 2016 12:32:01 +0200 Subject: [PATCH 12/37] avcodec: Bump micro version after changing public JPEG 2000 defines --- doc/APIchanges | 3 +++ libavcodec/version.h | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/APIchanges b/doc/APIchanges index 8f6cdca467..6cd0a49e58 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,9 @@ libavutil: 2015-08-28 API changes, most recent first: +2016-xx-xx - xxxxxxx - lavc 57.19.1 - avcodec.h + Adjust values for JPEG 2000 profiles. + 2016-xx-xx - xxxxxxx - lavf 57.7.0 - avio.h Add AVIODataMarkerType, write_data_type, ignore_boundary_point and avio_write_marker. diff --git a/libavcodec/version.h b/libavcodec/version.h index ef5b7420eb..4bfa09ca89 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #define LIBAVCODEC_VERSION_MAJOR 57 #define LIBAVCODEC_VERSION_MINOR 19 -#define LIBAVCODEC_VERSION_MICRO 0 +#define LIBAVCODEC_VERSION_MICRO 1 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ From 3fdffc032e8ea5676bc0c2551b900c0dc887835b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Tue, 24 May 2016 11:20:28 +0300 Subject: [PATCH 13/37] rtsp: Use avcodec_descriptor_get instead of avcodec_find_decoder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is only used for logging a human readable codec name for debugging. Signed-off-by: Martin Storsjö --- libavformat/rtsp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index 9e8733a108..b9416d2606 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -242,7 +242,7 @@ static int sdp_parse_rtpmap(AVFormatContext *s, AVCodecParameters *par = st->codecpar; char buf[256]; int i; - AVCodec *c; + const AVCodecDescriptor *desc; const char *c_name; /* See if we can handle this kind of payload. @@ -268,9 +268,9 @@ static int sdp_parse_rtpmap(AVFormatContext *s, par->codec_id = ff_rtp_codec_id(buf, par->codec_type); } - c = avcodec_find_decoder(par->codec_id); - if (c && c->name) - c_name = c->name; + desc = avcodec_descriptor_get(par->codec_id); + if (desc && desc->name) + c_name = desc->name; else c_name = "(null)"; From 07377fb557909015338b4c215b87b9c73ea577ad Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 23 May 2016 22:15:10 +0200 Subject: [PATCH 14/37] fate: More fine-grained dependencies for voice codec tests --- tests/fate/voice.mak | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tests/fate/voice.mak b/tests/fate/voice.mak index 975936c3ef..84f380d510 100644 --- a/tests/fate/voice.mak +++ b/tests/fate/voice.mak @@ -1,13 +1,13 @@ -FATE_G722 += fate-g722dec-1 +FATE_G722-$(call DEMDEC, G722, ADPCM_G722) += fate-g722dec-1 fate-g722dec-1: CMD = framecrc -i $(TARGET_SAMPLES)/g722/conf-adminmenu-162.g722 -FATE_G722 += fate-g722-encode +FATE_G722-$(call ENCDEC, ADPCM_G722, G722) += fate-g722-encode fate-g722-encode: tests/data/asynth-16000-1.wav fate-g722-encode: SRC = tests/data/asynth-16000-1.wav fate-g722-encode: CMD = enc_dec_pcm wav md5 s16le $(SRC) -c:a g722 -FATE_SAMPLES_AVCONV += $(FATE_G722) -fate-g722: $(FATE_G722) +FATE_SAMPLES_AVCONV += $(FATE_G722-yes) +fate-g722: $(FATE_G722-yes) FATE_G723_1 += fate-g723_1-dec-1 fate-g723_1-dec-1: CMD = framecrc -postfilter 0 -i $(TARGET_SAMPLES)/g723_1/ineqd53.tco @@ -33,7 +33,7 @@ fate-g723_1-dec-7: CMD = framecrc -postfilter 1 -i $(TARGET_SAMPLES)/g723_1/dtx6 FATE_G723_1 += fate-g723_1-dec-8 fate-g723_1-dec-8: CMD = framecrc -postfilter 1 -i $(TARGET_SAMPLES)/g723_1/dtx63e.tco -FATE_SAMPLES_AVCONV += $(FATE_G723_1) +FATE_SAMPLES_AVCONV-$(call DEMDEC, G723_1, G723_1) += $(FATE_G723_1) fate-g723_1: $(FATE_G723_1) FATE_G726 += fate-g726-encode-2bit @@ -51,24 +51,24 @@ fate-g726-encode-5bit: CMD = enc_dec_pcm wav md5 s16le $(SRC) -c:a g726 -b:a 40k $(FATE_G726): tests/data/asynth-8000-1.wav $(FATE_G726): SRC = tests/data/asynth-8000-1.wav -FATE_SAMPLES_AVCONV += $(FATE_G726) +FATE_SAMPLES_AVCONV-$(call ENCDEC, ADPCM_G726, WAV) += $(FATE_G726) fate-g726: $(FATE_G726) -FATE_GSM += fate-gsm-ms +FATE_GSM-$(call DEMDEC, WAV, GSM_MS) += fate-gsm-ms fate-gsm-ms: CMD = framecrc -i $(TARGET_SAMPLES)/gsm/ciao.wav -FATE_GSM += fate-gsm-toast +FATE_GSM-$(call DEMDEC, MOV, GSM) += fate-gsm-toast fate-gsm-toast: CMD = framecrc -i $(TARGET_SAMPLES)/gsm/sample-gsm-8000.mov -t 10 -FATE_SAMPLES_AVCONV += $(FATE_GSM) -fate-gsm: $(FATE_GSM) +FATE_SAMPLES_AVCONV += $(FATE_GSM-yes) +fate-gsm: $(FATE_GSM-yes) -FATE_SAMPLES_AVCONV += fate-qcelp +FATE_SAMPLES_AVCONV-$(call DEMDEC, QCP, QCELP) += fate-qcelp fate-qcelp: CMD = pcm -i $(TARGET_SAMPLES)/qcp/0036580847.QCP fate-qcelp: CMP = oneoff fate-qcelp: REF = $(SAMPLES)/qcp/0036580847.pcm -FATE_SAMPLES_AVCONV += fate-truespeech +FATE_SAMPLES_AVCONV-$(call DEMDEC, WAV, TRUESPEECH) += fate-truespeech fate-truespeech: CMD = pcm -i $(TARGET_SAMPLES)/truespeech/a6.wav fate-truespeech: CMP = oneoff fate-truespeech: REF = $(SAMPLES)/truespeech/a6.pcm From 7ca4fdc046a945949866bb6fc550e3cab1fc8c00 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 23 May 2016 22:15:43 +0200 Subject: [PATCH 15/37] fate: More fine-grained dependencies for demuxer tests --- tests/fate/demux.mak | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/fate/demux.mak b/tests/fate/demux.mak index 2446b90b03..d529341a5d 100644 --- a/tests/fate/demux.mak +++ b/tests/fate/demux.mak @@ -1,4 +1,4 @@ -FATE_SAMPLES_AVCONV-$(CONFIG_AAC_DEMUXER) += fate-adts-demux +FATE_SAMPLES_AVCONV-$(call DEMDEC, AAC, AAC) += fate-adts-demux fate-adts-demux: CMD = crc -i $(TARGET_SAMPLES)/aac/ct_faac-adts.aac -acodec copy FATE_SAMPLES_AVCONV-$(CONFIG_AEA_DEMUXER) += fate-aea-demux @@ -16,10 +16,10 @@ fate-cdxl-demux: CMD = framecrc -i $(TARGET_SAMPLES)/cdxl/mirage.cdxl -vcodec co FATE_SAMPLES_AVCONV-$(CONFIG_DAUD_DEMUXER) += fate-d-cinema-demux fate-d-cinema-demux: CMD = framecrc -i $(TARGET_SAMPLES)/d-cinema/THX_Science_FLT_1920-partial.302 -acodec copy -FATE_SAMPLES_AVCONV-$(CONFIG_IV8_DEMUXER) += fate-iv8-demux +FATE_SAMPLES_AVCONV-$(call ALLYES, IV8_DEMUXER MPEG4VIDEO_PARSER) += fate-iv8-demux fate-iv8-demux: CMD = framecrc -i $(TARGET_SAMPLES)/iv8/zzz-partial.mpg -vcodec copy -FATE_SAMPLES_AVCONV-$(CONFIG_LMLM4_DEMUXER) += fate-lmlm4-demux +FATE_SAMPLES_AVCONV-$(call ALLYES, LMLM4_DEMUXER MPEG4VIDEO_PARSER) += fate-lmlm4-demux fate-lmlm4-demux: CMD = framecrc -i $(TARGET_SAMPLES)/lmlm4/LMLM4_CIFat30fps.divx -t 3 -acodec copy -vcodec copy FATE_SAMPLES_AVCONV-$(CONFIG_XA_DEMUXER) += fate-maxis-xa @@ -28,10 +28,10 @@ fate-maxis-xa: CMD = framecrc -i $(TARGET_SAMPLES)/maxis-xa/SC2KBUG.XA -frames:a FATE_SAMPLES_AVCONV-$(CONFIG_MTV_DEMUXER) += fate-mtv fate-mtv: CMD = framecrc -i $(TARGET_SAMPLES)/mtv/comedian_auto-partial.mtv -c copy -FATE_SAMPLES_AVCONV-$(CONFIG_MXF_DEMUXER) += fate-mxf-demux +FATE_SAMPLES_AVCONV-$(call DEMDEC, MXF, MPEG4) += fate-mxf-demux fate-mxf-demux: CMD = framecrc -i $(TARGET_SAMPLES)/mxf/C0023S01.mxf -acodec copy -vcodec copy -FATE_SAMPLES_AVCONV-$(CONFIG_NC_DEMUXER) += fate-nc-demux +FATE_SAMPLES_AVCONV-$(call ALLYES, NC_DEMUXER MPEG4VIDEO_PARSER) += fate-nc-demux fate-nc-demux: CMD = framecrc -i $(TARGET_SAMPLES)/nc-camera/nc-sample-partial -vcodec copy FATE_SAMPLES_AVCONV-$(CONFIG_NSV_DEMUXER) += fate-nsv-demux @@ -61,7 +61,7 @@ fate-smjpeg-demux: CMD = framecrc -i $(TARGET_SAMPLES)/smjpeg/scenwin.mjpg -c co FATE_SAMPLES_AVCONV-$(CONFIG_WSAUD_DEMUXER) += fate-westwood-aud fate-westwood-aud: CMD = framecrc -i $(TARGET_SAMPLES)/westwood-aud/excellent.aud -c copy -FATE_SAMPLES_AVCONV-$(CONFIG_WTV_DEMUXER) += fate-wtv-demux +FATE_SAMPLES_AVCONV-$(call ALLYES, WTV_DEMUXER MPEGVIDEO_PARSER) += fate-wtv-demux fate-wtv-demux: CMD = framecrc -i $(TARGET_SAMPLES)/wtv/law-and-order-partial.wtv -vcodec copy -acodec copy FATE_SAMPLES_AVCONV-$(CONFIG_XMV_DEMUXER) += fate-xmv-demux From 4024b566d664a4b161d677554be52f32e7ad4236 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 24 May 2016 01:20:34 +0200 Subject: [PATCH 16/37] golomb: Give svq3_get_se_golomb()/svq3_get_ue_golomb() better names --- libavcodec/dirac.c | 58 ++++++++++++++++++++++----------------------- libavcodec/golomb.h | 6 ++--- libavcodec/rv30.c | 4 ++-- libavcodec/rv34.c | 4 ++-- libavcodec/rv40.c | 2 +- libavcodec/svq3.c | 24 +++++++++---------- 6 files changed, 49 insertions(+), 49 deletions(-) diff --git a/libavcodec/dirac.c b/libavcodec/dirac.c index aced2ac073..142af20579 100644 --- a/libavcodec/dirac.c +++ b/libavcodec/dirac.c @@ -148,8 +148,8 @@ static int parse_source_parameters(AVDiracSeqHeader *dsh, GetBitContext *gb, /* [DIRAC_STD] 10.3.2 Frame size. frame_size(video_params) */ /* [DIRAC_STD] custom_dimensions_flag */ if (get_bits1(gb)) { - dsh->width = svq3_get_ue_golomb(gb); /* [DIRAC_STD] FRAME_WIDTH */ - dsh->height = svq3_get_ue_golomb(gb); /* [DIRAC_STD] FRAME_HEIGHT */ + dsh->width = get_interleaved_ue_golomb(gb); /* [DIRAC_STD] FRAME_WIDTH */ + dsh->height = get_interleaved_ue_golomb(gb); /* [DIRAC_STD] FRAME_HEIGHT */ } /* [DIRAC_STD] 10.3.3 Chroma Sampling Format. @@ -157,7 +157,7 @@ static int parse_source_parameters(AVDiracSeqHeader *dsh, GetBitContext *gb, /* [DIRAC_STD] custom_chroma_format_flag */ if (get_bits1(gb)) /* [DIRAC_STD] CHROMA_FORMAT_INDEX */ - dsh->chroma_format = svq3_get_ue_golomb(gb); + dsh->chroma_format = get_interleaved_ue_golomb(gb); if (dsh->chroma_format > 2) { if (log_ctx) av_log(log_ctx, AV_LOG_ERROR, "Unknown chroma format %d\n", @@ -169,22 +169,22 @@ static int parse_source_parameters(AVDiracSeqHeader *dsh, GetBitContext *gb, /* [DIRAC_STD] custom_scan_format_flag */ if (get_bits1(gb)) /* [DIRAC_STD] SOURCE_SAMPLING */ - dsh->interlaced = svq3_get_ue_golomb(gb); + dsh->interlaced = get_interleaved_ue_golomb(gb); if (dsh->interlaced > 1) return AVERROR_INVALIDDATA; /* [DIRAC_STD] 10.3.5 Frame Rate. frame_rate(video_params) */ if (get_bits1(gb)) { /* [DIRAC_STD] custom_frame_rate_flag */ - dsh->frame_rate_index = svq3_get_ue_golomb(gb); + dsh->frame_rate_index = get_interleaved_ue_golomb(gb); if (dsh->frame_rate_index > 10) return AVERROR_INVALIDDATA; if (!dsh->frame_rate_index) { /* [DIRAC_STD] FRAME_RATE_NUMER */ - frame_rate.num = svq3_get_ue_golomb(gb); + frame_rate.num = get_interleaved_ue_golomb(gb); /* [DIRAC_STD] FRAME_RATE_DENOM */ - frame_rate.den = svq3_get_ue_golomb(gb); + frame_rate.den = get_interleaved_ue_golomb(gb); } } /* [DIRAC_STD] preset_frame_rate(video_params, index) */ @@ -201,14 +201,14 @@ static int parse_source_parameters(AVDiracSeqHeader *dsh, GetBitContext *gb, * pixel_aspect_ratio(video_params) */ if (get_bits1(gb)) { /* [DIRAC_STD] custom_pixel_aspect_ratio_flag */ /* [DIRAC_STD] index */ - dsh->aspect_ratio_index = svq3_get_ue_golomb(gb); + dsh->aspect_ratio_index = get_interleaved_ue_golomb(gb); if (dsh->aspect_ratio_index > 6) return AVERROR_INVALIDDATA; if (!dsh->aspect_ratio_index) { - dsh->sample_aspect_ratio.num = svq3_get_ue_golomb(gb); - dsh->sample_aspect_ratio.den = svq3_get_ue_golomb(gb); + dsh->sample_aspect_ratio.num = get_interleaved_ue_golomb(gb); + dsh->sample_aspect_ratio.den = get_interleaved_ue_golomb(gb); } } /* [DIRAC_STD] Take value from Table 10.4 Available preset pixel @@ -220,13 +220,13 @@ static int parse_source_parameters(AVDiracSeqHeader *dsh, GetBitContext *gb, /* [DIRAC_STD] 10.3.7 Clean area. clean_area(video_params) */ if (get_bits1(gb)) { /* [DIRAC_STD] custom_clean_area_flag */ /* [DIRAC_STD] CLEAN_WIDTH */ - dsh->clean_width = svq3_get_ue_golomb(gb); + dsh->clean_width = get_interleaved_ue_golomb(gb); /* [DIRAC_STD] CLEAN_HEIGHT */ - dsh->clean_height = svq3_get_ue_golomb(gb); + dsh->clean_height = get_interleaved_ue_golomb(gb); /* [DIRAC_STD] CLEAN_LEFT_OFFSET */ - dsh->clean_left_offset = svq3_get_ue_golomb(gb); + dsh->clean_left_offset = get_interleaved_ue_golomb(gb); /* [DIRAC_STD] CLEAN_RIGHT_OFFSET */ - dsh->clean_right_offset = svq3_get_ue_golomb(gb); + dsh->clean_right_offset = get_interleaved_ue_golomb(gb); } /* [DIRAC_STD] 10.3.8 Signal range. signal_range(video_params) @@ -234,17 +234,17 @@ static int parse_source_parameters(AVDiracSeqHeader *dsh, GetBitContext *gb, * AVCOL_RANGE_MPEG/JPEG values */ if (get_bits1(gb)) { /* [DIRAC_STD] custom_signal_range_flag */ /* [DIRAC_STD] index */ - dsh->pixel_range_index = svq3_get_ue_golomb(gb); + dsh->pixel_range_index = get_interleaved_ue_golomb(gb); if (dsh->pixel_range_index > 4) return AVERROR_INVALIDDATA; // This assumes either fullrange or MPEG levels only if (!dsh->pixel_range_index) { - luma_offset = svq3_get_ue_golomb(gb); - luma_depth = av_log2(svq3_get_ue_golomb(gb)) + 1; - svq3_get_ue_golomb(gb); /* chroma offset */ - svq3_get_ue_golomb(gb); /* chroma excursion */ + luma_offset = get_interleaved_ue_golomb(gb); + luma_depth = av_log2(get_interleaved_ue_golomb(gb)) + 1; + get_interleaved_ue_golomb(gb); /* chroma offset */ + get_interleaved_ue_golomb(gb); /* chroma excursion */ dsh->color_range = luma_offset ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; } @@ -265,7 +265,7 @@ static int parse_source_parameters(AVDiracSeqHeader *dsh, GetBitContext *gb, /* [DIRAC_STD] 10.3.9 Colour specification. colour_spec(video_params) */ if (get_bits1(gb)) { /* [DIRAC_STD] custom_colour_spec_flag */ /* [DIRAC_STD] index */ - idx = dsh->color_spec_index = svq3_get_ue_golomb(gb); + idx = dsh->color_spec_index = get_interleaved_ue_golomb(gb); if (dsh->color_spec_index > 4) return AVERROR_INVALIDDATA; @@ -277,20 +277,20 @@ static int parse_source_parameters(AVDiracSeqHeader *dsh, GetBitContext *gb, if (!dsh->color_spec_index) { /* [DIRAC_STD] 10.3.9.1 Colour primaries */ if (get_bits1(gb)) { - idx = svq3_get_ue_golomb(gb); + idx = get_interleaved_ue_golomb(gb); if (idx < 3) dsh->color_primaries = dirac_primaries[idx]; } /* [DIRAC_STD] 10.3.9.2 Colour matrix */ if (get_bits1(gb)) { - idx = svq3_get_ue_golomb(gb); + idx = get_interleaved_ue_golomb(gb); if (!idx) dsh->colorspace = AVCOL_SPC_BT709; else if (idx == 1) dsh->colorspace = AVCOL_SPC_BT470BG; } /* [DIRAC_STD] 10.3.9.3 Transfer function */ - if (get_bits1(gb) && !svq3_get_ue_golomb(gb)) + if (get_bits1(gb) && !get_interleaved_ue_golomb(gb)) dsh->color_trc = AVCOL_TRC_BT709; } } else { @@ -323,13 +323,13 @@ int av_dirac_parse_sequence_header(AVDiracSeqHeader **pdsh, goto fail; /* [DIRAC_SPEC] 10.1 Parse Parameters. parse_parameters() */ - version_major = svq3_get_ue_golomb(&gb); - svq3_get_ue_golomb(&gb); /* version_minor */ - dsh->profile = svq3_get_ue_golomb(&gb); - dsh->level = svq3_get_ue_golomb(&gb); + version_major = get_interleaved_ue_golomb(&gb); + get_interleaved_ue_golomb(&gb); /* version_minor */ + dsh->profile = get_interleaved_ue_golomb(&gb); + dsh->level = get_interleaved_ue_golomb(&gb); /* [DIRAC_SPEC] sequence_header() -> base_video_format as defined in * 10.2 Base Video Format, table 10.1 Dirac predefined video formats */ - video_format = svq3_get_ue_golomb(&gb); + video_format = get_interleaved_ue_golomb(&gb); if (log_ctx) { if (version_major < 2) @@ -366,7 +366,7 @@ int av_dirac_parse_sequence_header(AVDiracSeqHeader **pdsh, /* [DIRAC_STD] picture_coding_mode shall be 0 for fields and 1 for frames * currently only used to signal field coding */ - picture_coding_mode = svq3_get_ue_golomb(&gb); + picture_coding_mode = get_interleaved_ue_golomb(&gb); if (picture_coding_mode != 0) { if (log_ctx) { av_log(log_ctx, AV_LOG_ERROR, "Unsupported picture coding mode %d", diff --git a/libavcodec/golomb.h b/libavcodec/golomb.h index 398fe3b30a..2d0be89e35 100644 --- a/libavcodec/golomb.h +++ b/libavcodec/golomb.h @@ -108,7 +108,7 @@ static inline int get_ue_golomb_31(GetBitContext *gb) return ff_ue_golomb_vlc_code[buf]; } -static inline unsigned svq3_get_ue_golomb(GetBitContext *gb) +static inline unsigned get_interleaved_ue_golomb(GetBitContext *gb) { uint32_t buf; @@ -218,7 +218,7 @@ static inline int get_se_golomb_long(GetBitContext *gb) return buf; } -static inline int svq3_get_se_golomb(GetBitContext *gb) +static inline int get_interleaved_se_golomb(GetBitContext *gb) { unsigned int buf; @@ -253,7 +253,7 @@ static inline int svq3_get_se_golomb(GetBitContext *gb) static inline int dirac_get_se_golomb(GetBitContext *gb) { - uint32_t ret = svq3_get_ue_golomb(gb); + uint32_t ret = get_interleaved_ue_golomb(gb); if (ret) { uint32_t buf; diff --git a/libavcodec/rv30.c b/libavcodec/rv30.c index bf22df5f10..7218fa36dc 100644 --- a/libavcodec/rv30.c +++ b/libavcodec/rv30.c @@ -81,7 +81,7 @@ static int rv30_decode_intra_types(RV34DecContext *r, GetBitContext *gb, int8_t for(i = 0; i < 4; i++, dst += r->intra_types_stride - 4){ for(j = 0; j < 4; j+= 2){ - unsigned code = svq3_get_ue_golomb(gb) << 1; + unsigned code = get_interleaved_ue_golomb(gb) << 1; if(code >= 81*2){ av_log(r->s.avctx, AV_LOG_ERROR, "Incorrect intra prediction code\n"); return -1; @@ -109,7 +109,7 @@ static int rv30_decode_mb_info(RV34DecContext *r) static const int rv30_b_types[6] = { RV34_MB_SKIP, RV34_MB_B_DIRECT, RV34_MB_B_FORWARD, RV34_MB_B_BACKWARD, RV34_MB_TYPE_INTRA, RV34_MB_TYPE_INTRA16x16 }; MpegEncContext *s = &r->s; GetBitContext *gb = &s->gb; - unsigned code = svq3_get_ue_golomb(gb); + unsigned code = get_interleaved_ue_golomb(gb); if (code > 11) { av_log(s->avctx, AV_LOG_ERROR, "Incorrect MB type code\n"); diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c index 5fa71d87c8..4220195a52 100644 --- a/libavcodec/rv34.c +++ b/libavcodec/rv34.c @@ -854,8 +854,8 @@ static int rv34_decode_mv(RV34DecContext *r, int block_type) memset(r->dmv, 0, sizeof(r->dmv)); for(i = 0; i < num_mvs[block_type]; i++){ - r->dmv[i][0] = svq3_get_se_golomb(gb); - r->dmv[i][1] = svq3_get_se_golomb(gb); + r->dmv[i][0] = get_interleaved_se_golomb(gb); + r->dmv[i][1] = get_interleaved_se_golomb(gb); } switch(block_type){ case RV34_MB_TYPE_INTRA: diff --git a/libavcodec/rv40.c b/libavcodec/rv40.c index e6c77e8710..0da13124d6 100644 --- a/libavcodec/rv40.c +++ b/libavcodec/rv40.c @@ -231,7 +231,7 @@ static int rv40_decode_mb_info(RV34DecContext *r) int mb_pos = s->mb_x + s->mb_y * s->mb_stride; if(!r->s.mb_skip_run) - r->s.mb_skip_run = svq3_get_ue_golomb(gb) + 1; + r->s.mb_skip_run = get_interleaved_ue_golomb(gb) + 1; if(--r->s.mb_skip_run) return RV34_MB_SKIP; diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c index b11e6ffc0d..9dc1fb5d02 100644 --- a/libavcodec/svq3.c +++ b/libavcodec/svq3.c @@ -290,7 +290,7 @@ static inline int svq3_decode_block(GetBitContext *gb, int16_t *block, const uint8_t *const scan = scan_patterns[type]; for (limit = (16 >> intra); index < 16; index = limit, limit += 8) { - for (; (vlc = svq3_get_ue_golomb(gb)) != 0; index++) { + for (; (vlc = get_interleaved_ue_golomb(gb)) != 0; index++) { int sign = (vlc & 1) ? 0 : -1; vlc = vlc + 1 >> 1; @@ -527,8 +527,8 @@ static inline int svq3_mc_dir(SVQ3Context *s, int size, int mode, if (mode == PREDICT_MODE) { dx = dy = 0; } else { - dy = svq3_get_se_golomb(&s->gb_slice); - dx = svq3_get_se_golomb(&s->gb_slice); + dy = get_interleaved_se_golomb(&s->gb_slice); + dx = get_interleaved_se_golomb(&s->gb_slice); if (dx == INVALID_VLC || dy == INVALID_VLC) { av_log(s->avctx, AV_LOG_ERROR, "invalid MV vlc\n"); @@ -839,7 +839,7 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type) /* decode prediction codes for luma blocks */ for (i = 0; i < 16; i += 2) { - vlc = svq3_get_ue_golomb(&s->gb_slice); + vlc = get_interleaved_ue_golomb(&s->gb_slice); if (vlc >= 25) { av_log(s->avctx, AV_LOG_ERROR, @@ -917,7 +917,7 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type) if (!IS_INTRA16x16(mb_type) && (!IS_SKIP(mb_type) || s->pict_type == AV_PICTURE_TYPE_B)) { - if ((vlc = svq3_get_ue_golomb(&s->gb_slice)) >= 48) { + if ((vlc = get_interleaved_ue_golomb(&s->gb_slice)) >= 48) { av_log(s->avctx, AV_LOG_ERROR, "cbp_vlc=%"PRIu32"\n", vlc); return -1; } @@ -927,7 +927,7 @@ static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type) } if (IS_INTRA16x16(mb_type) || (s->pict_type != AV_PICTURE_TYPE_I && s->adaptive_quant && cbp)) { - s->qscale += svq3_get_se_golomb(&s->gb_slice); + s->qscale += get_interleaved_se_golomb(&s->gb_slice); if (s->qscale > 31u) { av_log(s->avctx, AV_LOG_ERROR, "qscale:%d\n", s->qscale); @@ -1045,7 +1045,7 @@ static int svq3_decode_slice_header(AVCodecContext *avctx) skip_bits_long(&s->gb, slice_bytes * 8); } - if ((slice_id = svq3_get_ue_golomb(&s->gb_slice)) >= 3) { + if ((slice_id = get_interleaved_ue_golomb(&s->gb_slice)) >= 3) { av_log(s->avctx, AV_LOG_ERROR, "illegal slice type %u \n", slice_id); return -1; } @@ -1228,12 +1228,12 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) avctx->has_b_frames = !s->low_delay; if (s->unknown_flag) { #if CONFIG_ZLIB - unsigned watermark_width = svq3_get_ue_golomb(&gb); - unsigned watermark_height = svq3_get_ue_golomb(&gb); - int u1 = svq3_get_ue_golomb(&gb); + unsigned watermark_width = get_interleaved_ue_golomb(&gb); + unsigned watermark_height = get_interleaved_ue_golomb(&gb); + int u1 = get_interleaved_ue_golomb(&gb); int u2 = get_bits(&gb, 8); int u3 = get_bits(&gb, 2); - int u4 = svq3_get_ue_golomb(&gb); + int u4 = get_interleaved_ue_golomb(&gb); unsigned long buf_len = watermark_width * watermark_height * 4; int offset = get_bits_count(&gb) + 7 >> 3; @@ -1501,7 +1501,7 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data, /* TODO: support s->mb_skip_run */ } - mb_type = svq3_get_ue_golomb(&s->gb_slice); + mb_type = get_interleaved_ue_golomb(&s->gb_slice); if (s->pict_type == AV_PICTURE_TYPE_I) mb_type += 8; From 24b5cff01bbac4e08acfd6d19c499e880988f520 Mon Sep 17 00:00:00 2001 From: Andrey Turkin Date: Wed, 25 May 2016 14:16:14 +0300 Subject: [PATCH 17/37] lavc: handle hw_frames_ctx where necessary avcodec_copy_context() didn't handle hw_frames_ctx references correctly which could cause crashes. Signed-off-by: Anton Khirnov --- libavcodec/options.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libavcodec/options.c b/libavcodec/options.c index 117ae5e445..18613ace96 100644 --- a/libavcodec/options.c +++ b/libavcodec/options.c @@ -190,6 +190,7 @@ int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src) dest->inter_matrix = NULL; dest->rc_override = NULL; dest->subtitle_header = NULL; + dest->hw_frames_ctx = NULL; #if FF_API_MPV_OPT FF_DISABLE_DEPRECATION_WARNINGS dest->rc_eq = NULL; @@ -219,13 +220,21 @@ int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src) dest->subtitle_header_size = src->subtitle_header_size; #undef alloc_and_copy_or_fail + if (src->hw_frames_ctx) { + dest->hw_frames_ctx = av_buffer_ref(src->hw_frames_ctx); + if (!dest->hw_frames_ctx) + goto fail; + } + return 0; fail: + av_freep(&dest->subtitle_header); av_freep(&dest->rc_override); av_freep(&dest->intra_matrix); av_freep(&dest->inter_matrix); av_freep(&dest->extradata); + av_buffer_unref(&dest->hw_frames_ctx); #if FF_API_MPV_OPT FF_DISABLE_DEPRECATION_WARNINGS av_freep(&dest->rc_eq); From 1c9e8616c535ef496e7ee8a5cbc5e9e972a6977d Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 19 May 2016 15:59:25 +0200 Subject: [PATCH 18/37] hwcontext: add a function for opening devices --- doc/APIchanges | 3 +++ libavutil/hwcontext.c | 36 ++++++++++++++++++++++++++++++++++ libavutil/hwcontext.h | 28 ++++++++++++++++++++++++++ libavutil/hwcontext_internal.h | 3 +++ libavutil/version.h | 2 +- 5 files changed, 71 insertions(+), 1 deletion(-) diff --git a/doc/APIchanges b/doc/APIchanges index 6cd0a49e58..9f46edc15e 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,9 @@ libavutil: 2015-08-28 API changes, most recent first: +2016-xx-xx - xxxxxxx - lavu 55.13.0 - hwcontext.h + Add av_hwdevice_ctx_create(). + 2016-xx-xx - xxxxxxx - lavc 57.19.1 - avcodec.h Adjust values for JPEG 2000 profiles. diff --git a/libavutil/hwcontext.c b/libavutil/hwcontext.c index 2ddae90f10..3028b67a6c 100644 --- a/libavutil/hwcontext.c +++ b/libavutil/hwcontext.c @@ -452,3 +452,39 @@ void av_hwframe_constraints_free(AVHWFramesConstraints **constraints) } av_freep(constraints); } + +int av_hwdevice_ctx_create(AVBufferRef **pdevice_ref, enum AVHWDeviceType type, + const char *device, AVDictionary *opts, int flags) +{ + AVBufferRef *device_ref = NULL; + AVHWDeviceContext *device_ctx; + int ret = 0; + + device_ref = av_hwdevice_ctx_alloc(type); + if (!device_ref) { + ret = AVERROR(ENOMEM); + goto fail; + } + device_ctx = (AVHWDeviceContext*)device_ref->data; + + if (!device_ctx->internal->hw_type->device_create) { + ret = AVERROR(ENOSYS); + goto fail; + } + + ret = device_ctx->internal->hw_type->device_create(device_ctx, device, + opts, flags); + if (ret < 0) + goto fail; + + ret = av_hwdevice_ctx_init(device_ref); + if (ret < 0) + goto fail; + + *pdevice_ref = device_ref; + return 0; +fail: + av_buffer_unref(&device_ref); + *pdevice_ref = NULL; + return ret; +} diff --git a/libavutil/hwcontext.h b/libavutil/hwcontext.h index 505b1748be..d8e7c3f090 100644 --- a/libavutil/hwcontext.h +++ b/libavutil/hwcontext.h @@ -241,6 +241,34 @@ AVBufferRef *av_hwdevice_ctx_alloc(enum AVHWDeviceType type); */ int av_hwdevice_ctx_init(AVBufferRef *ref); +/** + * Open a device of the specified type and create an AVHWDeviceContext for it. + * + * This is a convenience function intended to cover the simple cases. Callers + * who need to fine-tune device creation/management should open the device + * manually and then wrap it in an AVHWDeviceContext using + * av_hwdevice_ctx_alloc()/av_hwdevice_ctx_init(). + * + * The returned context is already initialized and ready for use, the caller + * should not call av_hwdevice_ctx_init() on it. The user_opaque/free fields of + * the created AVHWDeviceContext are set by this function and should not be + * touched by the caller. + * + * @param device_ctx On success, a reference to the newly-created device context + * will be written here. The reference is owned by the caller + * and must be released with av_buffer_unref() when no longer + * needed. On failure, NULL will be written to this pointer. + * @param type The type of the device to create. + * @param device A type-specific string identifying the device to open. + * @param opts A dictionary of additional (type-specific) options to use in + * opening the device. The dictionary remains owned by the caller. + * @param flags currently unused + * + * @return 0 on success, a negative AVERROR code on failure. + */ +int av_hwdevice_ctx_create(AVBufferRef **device_ctx, enum AVHWDeviceType type, + const char *device, AVDictionary *opts, int flags); + /** * Allocate an AVHWFramesContext tied to a given device context. * diff --git a/libavutil/hwcontext_internal.h b/libavutil/hwcontext_internal.h index 281eae892b..2e1daaeeeb 100644 --- a/libavutil/hwcontext_internal.h +++ b/libavutil/hwcontext_internal.h @@ -64,6 +64,9 @@ typedef struct HWContextType { */ size_t frames_priv_size; + int (*device_create)(AVHWDeviceContext *ctx, const char *device, + AVDictionary *opts, int flags); + int (*device_init)(AVHWDeviceContext *ctx); void (*device_uninit)(AVHWDeviceContext *ctx); diff --git a/libavutil/version.h b/libavutil/version.h index 4cee2b0ba1..48a5878325 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -54,7 +54,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 55 -#define LIBAVUTIL_VERSION_MINOR 12 +#define LIBAVUTIL_VERSION_MINOR 13 #define LIBAVUTIL_VERSION_MICRO 0 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ From 38392b2af815898b8716826c4e29d95c04fb2647 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 19 May 2016 16:33:15 +0200 Subject: [PATCH 19/37] hwcontext_vdpau: implement device creation --- configure | 3 +- libavutil/hwcontext_vdpau.c | 81 +++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 43c563f16c..261200d511 100755 --- a/configure +++ b/configure @@ -4766,8 +4766,7 @@ enabled vdpau && disable vdpau enabled vdpau && enabled xlib && - check_func_headers "vdpau/vdpau.h vdpau/vdpau_x11.h" vdp_device_create_x11 -lvdpau && - prepend avconv_libs $($ldflags_filter "-lvdpau") && + check_lib2 "vdpau/vdpau.h vdpau/vdpau_x11.h" vdp_device_create_x11 -lvdpau && enable vdpau_x11 enabled debug && add_cflags -g"$debuglevel" && add_asflags -g"$debuglevel" diff --git a/libavutil/hwcontext_vdpau.c b/libavutil/hwcontext_vdpau.c index faae5f8641..9722c10b87 100644 --- a/libavutil/hwcontext_vdpau.c +++ b/libavutil/hwcontext_vdpau.c @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "config.h" + #include #include @@ -388,6 +390,82 @@ static int vdpau_transfer_data_to(AVHWFramesContext *ctx, AVFrame *dst, return 0; } +#if HAVE_VDPAU_X11 +#include +#include + +typedef struct VDPAUDevicePriv { + VdpDeviceDestroy *device_destroy; + Display *dpy; +} VDPAUDevicePriv; + +static void vdpau_device_free(AVHWDeviceContext *ctx) +{ + AVVDPAUDeviceContext *hwctx = ctx->hwctx; + VDPAUDevicePriv *priv = ctx->user_opaque; + + if (priv->device_destroy) + priv->device_destroy(hwctx->device); + if (priv->dpy) + XCloseDisplay(priv->dpy); + av_freep(&priv); +} + +static int vdpau_device_create(AVHWDeviceContext *ctx, const char *device, + AVDictionary *opts, int flags) +{ + AVVDPAUDeviceContext *hwctx = ctx->hwctx; + + VDPAUDevicePriv *priv; + VdpStatus err; + VdpGetInformationString *get_information_string; + const char *display, *vendor; + + priv = av_mallocz(sizeof(*priv)); + if (!priv) + return AVERROR(ENOMEM); + + ctx->user_opaque = priv; + ctx->free = vdpau_device_free; + + priv->dpy = XOpenDisplay(device); + if (!priv->dpy) { + av_log(ctx, AV_LOG_ERROR, "Cannot open the X11 display %s.\n", + XDisplayName(device)); + return AVERROR_UNKNOWN; + } + display = XDisplayString(priv->dpy); + + err = vdp_device_create_x11(priv->dpy, XDefaultScreen(priv->dpy), + &hwctx->device, &hwctx->get_proc_address); + if (err != VDP_STATUS_OK) { + av_log(ctx, AV_LOG_ERROR, "VDPAU device creation on X11 display %s failed.\n", + display); + return AVERROR_UNKNOWN; + } + +#define GET_CALLBACK(id, result) \ +do { \ + void *tmp; \ + err = hwctx->get_proc_address(hwctx->device, id, &tmp); \ + if (err != VDP_STATUS_OK) { \ + av_log(ctx, AV_LOG_ERROR, "Error getting the " #id " callback.\n"); \ + return AVERROR_UNKNOWN; \ + } \ + result = tmp; \ +} while (0) + + GET_CALLBACK(VDP_FUNC_ID_GET_INFORMATION_STRING, get_information_string); + GET_CALLBACK(VDP_FUNC_ID_DEVICE_DESTROY, priv->device_destroy); + + get_information_string(&vendor); + av_log(ctx, AV_LOG_VERBOSE, "Successfully created a VDPAU device (%s) on " + "X11 display %s\n", vendor, display); + + return 0; +} +#endif + const HWContextType ff_hwcontext_type_vdpau = { .type = AV_HWDEVICE_TYPE_VDPAU, .name = "VDPAU", @@ -396,6 +474,9 @@ const HWContextType ff_hwcontext_type_vdpau = { .device_priv_size = sizeof(VDPAUDeviceContext), .frames_priv_size = sizeof(VDPAUFramesContext), +#if HAVE_VDPAU_X11 + .device_create = vdpau_device_create, +#endif .device_init = vdpau_device_init, .device_uninit = vdpau_device_uninit, .frames_init = vdpau_frames_init, From 2e219b491bcc0845248345fdad31231b081e06d1 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 19 May 2016 19:19:20 +0200 Subject: [PATCH 20/37] hwcontext_cuda: implement device creation --- libavutil/hwcontext_cuda.c | 44 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/libavutil/hwcontext_cuda.c b/libavutil/hwcontext_cuda.c index 6b87b61175..b8781cec1b 100644 --- a/libavutil/hwcontext_cuda.c +++ b/libavutil/hwcontext_cuda.c @@ -253,6 +253,49 @@ static int cuda_transfer_data_to(AVHWFramesContext *ctx, AVFrame *dst, return 0; } +static void cuda_device_free(AVHWDeviceContext *ctx) +{ + AVCUDADeviceContext *hwctx = ctx->hwctx; + cuCtxDestroy(hwctx->cuda_ctx); +} + +static int cuda_device_create(AVHWDeviceContext *ctx, const char *device, + AVDictionary *opts, int flags) +{ + AVCUDADeviceContext *hwctx = ctx->hwctx; + CUdevice cu_device; + CUcontext dummy; + CUresult err; + int device_idx = 0; + + if (device) + device_idx = strtol(device, NULL, 0); + + err = cuInit(0); + if (err != CUDA_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Could not initialize the CUDA driver API\n"); + return AVERROR_UNKNOWN; + } + + err = cuDeviceGet(&cu_device, device_idx); + if (err != CUDA_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Could not get the device number %d\n", device_idx); + return AVERROR_UNKNOWN; + } + + err = cuCtxCreate(&hwctx->cuda_ctx, 0, cu_device); + if (err != CUDA_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Error creating a CUDA context\n"); + return AVERROR_UNKNOWN; + } + + cuCtxPopCurrent(&dummy); + + ctx->free = cuda_device_free; + + return 0; +} + const HWContextType ff_hwcontext_type_cuda = { .type = AV_HWDEVICE_TYPE_CUDA, .name = "CUDA", @@ -260,6 +303,7 @@ const HWContextType ff_hwcontext_type_cuda = { .device_hwctx_size = sizeof(AVCUDADeviceContext), .frames_priv_size = sizeof(CUDAFramesContext), + .device_create = cuda_device_create, .frames_init = cuda_frames_init, .frames_get_buffer = cuda_get_buffer, .transfer_get_formats = cuda_transfer_get_formats, From 8e70385a8ed06f96f1e9e35cf7b6788a5c56eded Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 19 May 2016 19:19:20 +0200 Subject: [PATCH 21/37] hwcontext_dxva2: implement device creation --- libavutil/hwcontext_dxva2.c | 133 ++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) diff --git a/libavutil/hwcontext_dxva2.c b/libavutil/hwcontext_dxva2.c index 62cca6f6a4..e2c27bf160 100644 --- a/libavutil/hwcontext_dxva2.c +++ b/libavutil/hwcontext_dxva2.c @@ -37,6 +37,9 @@ #include "pixdesc.h" #include "pixfmt.h" +typedef IDirect3D9* WINAPI pDirect3DCreate9(UINT); +typedef HRESULT WINAPI pCreateDeviceManager9(UINT *, IDirect3DDeviceManager9 **); + typedef struct DXVA2FramesContext { IDirect3DSurface9 **surfaces_internal; int nb_surfaces_used; @@ -47,6 +50,16 @@ typedef struct DXVA2FramesContext { D3DFORMAT format; } DXVA2FramesContext; +typedef struct DXVA2DevicePriv { + HMODULE d3dlib; + HMODULE dxva2lib; + + HANDLE device_handle; + + IDirect3D9 *d3d9; + IDirect3DDevice9 *d3d9device; +} DXVA2DevicePriv; + static const struct { D3DFORMAT d3d_format; enum AVPixelFormat pix_fmt; @@ -273,6 +286,125 @@ static int dxva2_transfer_data(AVHWFramesContext *ctx, AVFrame *dst, return 0; } +static void dxva2_device_free(AVHWDeviceContext *ctx) +{ + AVDXVA2DeviceContext *hwctx = ctx->hwctx; + DXVA2DevicePriv *priv = ctx->user_opaque; + + if (hwctx->devmgr && priv->device_handle != INVALID_HANDLE_VALUE) + IDirect3DDeviceManager9_CloseDeviceHandle(hwctx->devmgr, priv->device_handle); + + if (hwctx->devmgr) + IDirect3DDeviceManager9_Release(hwctx->devmgr); + + if (priv->d3d9device) + IDirect3DDevice9_Release(priv->d3d9device); + + if (priv->d3d9) + IDirect3D9_Release(priv->d3d9); + + if (priv->d3dlib) + FreeLibrary(priv->d3dlib); + + if (priv->dxva2lib) + FreeLibrary(priv->dxva2lib); + + av_freep(&ctx->user_opaque); +} + +static int dxva2_device_create(AVHWDeviceContext *ctx, const char *device, + AVDictionary *opts, int flags) +{ + AVDXVA2DeviceContext *hwctx = ctx->hwctx; + DXVA2DevicePriv *priv; + + pDirect3DCreate9 *createD3D = NULL; + pCreateDeviceManager9 *createDeviceManager = NULL; + D3DPRESENT_PARAMETERS d3dpp = {0}; + D3DDISPLAYMODE d3ddm; + unsigned resetToken = 0; + UINT adapter = D3DADAPTER_DEFAULT; + HRESULT hr; + + if (device) + adapter = atoi(device); + + priv = av_mallocz(sizeof(*priv)); + if (!priv) + return AVERROR(ENOMEM); + + ctx->user_opaque = priv; + ctx->free = dxva2_device_free; + + priv->device_handle = INVALID_HANDLE_VALUE; + + priv->d3dlib = LoadLibrary("d3d9.dll"); + if (!priv->d3dlib) { + av_log(ctx, AV_LOG_ERROR, "Failed to load D3D9 library\n"); + return AVERROR_UNKNOWN; + } + priv->dxva2lib = LoadLibrary("dxva2.dll"); + if (!priv->dxva2lib) { + av_log(ctx, AV_LOG_ERROR, "Failed to load DXVA2 library\n"); + return AVERROR_UNKNOWN; + } + + createD3D = (pDirect3DCreate9 *)GetProcAddress(priv->d3dlib, "Direct3DCreate9"); + if (!createD3D) { + av_log(ctx, AV_LOG_ERROR, "Failed to locate Direct3DCreate9\n"); + return AVERROR_UNKNOWN; + } + createDeviceManager = (pCreateDeviceManager9 *)GetProcAddress(priv->dxva2lib, + "DXVA2CreateDirect3DDeviceManager9"); + if (!createDeviceManager) { + av_log(ctx, AV_LOG_ERROR, "Failed to locate DXVA2CreateDirect3DDeviceManager9\n"); + return AVERROR_UNKNOWN; + } + + priv->d3d9 = createD3D(D3D_SDK_VERSION); + if (!priv->d3d9) { + av_log(ctx, AV_LOG_ERROR, "Failed to create IDirect3D object\n"); + return AVERROR_UNKNOWN; + } + + IDirect3D9_GetAdapterDisplayMode(priv->d3d9, adapter, &d3ddm); + d3dpp.Windowed = TRUE; + d3dpp.BackBufferWidth = 640; + d3dpp.BackBufferHeight = 480; + d3dpp.BackBufferCount = 0; + d3dpp.BackBufferFormat = d3ddm.Format; + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + d3dpp.Flags = D3DPRESENTFLAG_VIDEO; + + hr = IDirect3D9_CreateDevice(priv->d3d9, adapter, D3DDEVTYPE_HAL, GetShellWindow(), + D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE, + &d3dpp, &priv->d3d9device); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Failed to create Direct3D device\n"); + return AVERROR_UNKNOWN; + } + + hr = createDeviceManager(&resetToken, &hwctx->devmgr); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Failed to create Direct3D device manager\n"); + return AVERROR_UNKNOWN; + } + + hr = IDirect3DDeviceManager9_ResetDevice(hwctx->devmgr, priv->d3d9device, resetToken); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Failed to bind Direct3D device to device manager\n"); + return AVERROR_UNKNOWN; + } + + hr = IDirect3DDeviceManager9_OpenDeviceHandle(hwctx->devmgr, &priv->device_handle); + if (FAILED(hr)) { + av_log(ctx, AV_LOG_ERROR, "Failed to open device handle\n"); + return AVERROR_UNKNOWN; + } + + return 0; +} + const HWContextType ff_hwcontext_type_dxva2 = { .type = AV_HWDEVICE_TYPE_DXVA2, .name = "DXVA2", @@ -281,6 +413,7 @@ const HWContextType ff_hwcontext_type_dxva2 = { .frames_hwctx_size = sizeof(AVDXVA2FramesContext), .frames_priv_size = sizeof(DXVA2FramesContext), + .device_create = dxva2_device_create, .frames_init = dxva2_frames_init, .frames_uninit = dxva2_frames_uninit, .frames_get_buffer = dxva2_get_buffer, From b8bf9194af602cf3a4bcd19a5e278e3d6d69f8fa Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 19 May 2016 19:19:20 +0200 Subject: [PATCH 22/37] hwcontext_vaapi: implement device creation --- libavutil/hwcontext_vaapi.c | 123 ++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/libavutil/hwcontext_vaapi.c b/libavutil/hwcontext_vaapi.c index 1a385ba514..4563e147f6 100644 --- a/libavutil/hwcontext_vaapi.c +++ b/libavutil/hwcontext_vaapi.c @@ -16,6 +16,21 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "config.h" + +#if HAVE_VAAPI_X11 +# include +#endif +#if HAVE_VAAPI_DRM +# include +#endif + +#include +#if HAVE_UNISTD_H +# include +#endif + + #include "avassert.h" #include "buffer.h" #include "common.h" @@ -26,6 +41,14 @@ #include "pixdesc.h" #include "pixfmt.h" +typedef struct VAAPIDevicePriv { +#if HAVE_VAAPI_X11 + Display *x11_display; +#endif + + int drm_fd; +} VAAPIDevicePriv; + typedef struct VAAPISurfaceFormat { enum AVPixelFormat pix_fmt; VAImageFormat image_format; @@ -823,6 +846,105 @@ fail: return err; } +static void vaapi_device_free(AVHWDeviceContext *ctx) +{ + AVVAAPIDeviceContext *hwctx = ctx->hwctx; + VAAPIDevicePriv *priv = ctx->user_opaque; + + if (hwctx->display) + vaTerminate(hwctx->display); + +#if HAVE_VAAPI_X11 + if (priv->x11_display) + XCloseDisplay(priv->x11_display); +#endif + + if (priv->drm_fd >= 0) + close(priv->drm_fd); + + av_freep(&priv); +} + +static int vaapi_device_create(AVHWDeviceContext *ctx, const char *device, + AVDictionary *opts, int flags) +{ + AVVAAPIDeviceContext *hwctx = ctx->hwctx; + VAAPIDevicePriv *priv; + VADisplay display = 0; + VAStatus vas; + int major, minor; + + priv = av_mallocz(sizeof(*priv)); + if (!priv) + return AVERROR(ENOMEM); + + priv->drm_fd = -1; + + ctx->user_opaque = priv; + ctx->free = vaapi_device_free; + +#if HAVE_VAAPI_X11 + if (!display && !(device && device[0] == '/')) { + // Try to open the device as an X11 display. + priv->x11_display = XOpenDisplay(device); + if (!priv->x11_display) { + av_log(ctx, AV_LOG_VERBOSE, "Cannot open X11 display " + "%s.\n", XDisplayName(device)); + } else { + display = vaGetDisplay(priv->x11_display); + if (!display) { + av_log(ctx, AV_LOG_ERROR, "Cannot open a VA display " + "from X11 display %s.\n", XDisplayName(device)); + return AVERROR_UNKNOWN; + } + + av_log(ctx, AV_LOG_VERBOSE, "Opened VA display via " + "X11 display %s.\n", XDisplayName(device)); + } + } +#endif + +#if HAVE_VAAPI_DRM + if (!display && device) { + // Try to open the device as a DRM path. + priv->drm_fd = open(device, O_RDWR); + if (priv->drm_fd < 0) { + av_log(ctx, AV_LOG_VERBOSE, "Cannot open DRM device %s.\n", + device); + } else { + display = vaGetDisplayDRM(priv->drm_fd); + if (!display) { + av_log(ctx, AV_LOG_ERROR, "Cannot open a VA display " + "from DRM device %s.\n", device); + return AVERROR_UNKNOWN; + } + + av_log(ctx, AV_LOG_VERBOSE, "Opened VA display via " + "DRM device %s.\n", device); + } + } +#endif + + if (!display) { + av_log(ctx, AV_LOG_ERROR, "No VA display found for " + "device: %s.\n", device ? device : ""); + return AVERROR(EINVAL); + } + + hwctx->display = display; + + vas = vaInitialize(display, &major, &minor); + if (vas != VA_STATUS_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Failed to initialise VAAPI " + "connection: %d (%s).\n", vas, vaErrorStr(vas)); + return AVERROR(EIO); + } + av_log(ctx, AV_LOG_VERBOSE, "Initialised VAAPI connection: " + "version %d.%d\n", major, minor); + + return 0; +} + const HWContextType ff_hwcontext_type_vaapi = { .type = AV_HWDEVICE_TYPE_VAAPI, .name = "VAAPI", @@ -833,6 +955,7 @@ const HWContextType ff_hwcontext_type_vaapi = { .frames_hwctx_size = sizeof(AVVAAPIFramesContext), .frames_priv_size = sizeof(VAAPIFramesContext), + .device_create = &vaapi_device_create, .device_init = &vaapi_device_init, .device_uninit = &vaapi_device_uninit, .frames_get_constraints = &vaapi_frames_get_constraints, From f72db3f2f3a8c83a4f5dede8fa03434b2bf676c6 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 19 May 2016 19:08:06 +0200 Subject: [PATCH 23/37] avconv_vdpau: use the hwcontext device creation API --- avconv_vdpau.c | 95 ++++---------------------------------------------- 1 file changed, 7 insertions(+), 88 deletions(-) diff --git a/avconv_vdpau.c b/avconv_vdpau.c index b58949e00d..5fedceef95 100644 --- a/avconv_vdpau.c +++ b/avconv_vdpau.c @@ -18,11 +18,6 @@ #include -#include -#include - -#include - #include "avconv.h" #include "libavcodec/vdpau.h" @@ -38,23 +33,6 @@ typedef struct VDPAUContext { AVFrame *tmp_frame; } VDPAUContext; -typedef struct VDPAUHWDevicePriv { - VdpDeviceDestroy *device_destroy; - Display *dpy; -} VDPAUHWDevicePriv; - -static void device_free(AVHWDeviceContext *ctx) -{ - AVVDPAUDeviceContext *hwctx = ctx->hwctx; - VDPAUHWDevicePriv *priv = ctx->user_opaque; - - if (priv->device_destroy) - priv->device_destroy(hwctx->device); - if (priv->dpy) - XCloseDisplay(priv->dpy); - av_freep(&priv); -} - static void vdpau_uninit(AVCodecContext *s) { InputStream *ist = s->opaque; @@ -106,15 +84,8 @@ static int vdpau_alloc(AVCodecContext *s) InputStream *ist = s->opaque; int loglevel = (ist->hwaccel_id == HWACCEL_AUTO) ? AV_LOG_VERBOSE : AV_LOG_ERROR; VDPAUContext *ctx; - const char *display, *vendor; - VdpStatus err; int ret; - VdpDevice device; - VdpGetProcAddress *get_proc_address; - VdpGetInformationString *get_information_string; - - VDPAUHWDevicePriv *device_priv = NULL; AVBufferRef *device_ref = NULL; AVHWDeviceContext *device_ctx; AVVDPAUDeviceContext *device_hwctx; @@ -124,10 +95,6 @@ static int vdpau_alloc(AVCodecContext *s) if (!ctx) return AVERROR(ENOMEM); - device_priv = av_mallocz(sizeof(*device_priv)); - if (!device_priv) - goto fail; - ist->hwaccel_ctx = ctx; ist->hwaccel_uninit = vdpau_uninit; ist->hwaccel_get_buffer = vdpau_get_buffer; @@ -137,51 +104,12 @@ static int vdpau_alloc(AVCodecContext *s) if (!ctx->tmp_frame) goto fail; - device_priv->dpy = XOpenDisplay(ist->hwaccel_device); - if (!device_priv->dpy) { - av_log(NULL, loglevel, "Cannot open the X11 display %s.\n", - XDisplayName(ist->hwaccel_device)); - goto fail; - } - display = XDisplayString(device_priv->dpy); - - err = vdp_device_create_x11(device_priv->dpy, XDefaultScreen(device_priv->dpy), - &device, &get_proc_address); - if (err != VDP_STATUS_OK) { - av_log(NULL, loglevel, "VDPAU device creation on X11 display %s failed.\n", - display); - goto fail; - } - -#define GET_CALLBACK(id, result) \ -do { \ - void *tmp; \ - err = get_proc_address(device, id, &tmp); \ - if (err != VDP_STATUS_OK) { \ - av_log(NULL, loglevel, "Error getting the " #id " callback.\n"); \ - goto fail; \ - } \ - result = tmp; \ -} while (0) - - GET_CALLBACK(VDP_FUNC_ID_GET_INFORMATION_STRING, get_information_string); - GET_CALLBACK(VDP_FUNC_ID_DEVICE_DESTROY, device_priv->device_destroy); - - device_ref = av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_VDPAU); - if (!device_ref) - goto fail; - device_ctx = (AVHWDeviceContext*)device_ref->data; - device_hwctx = device_ctx->hwctx; - device_ctx->user_opaque = device_priv; - device_ctx->free = device_free; - device_hwctx->device = device; - device_hwctx->get_proc_address = get_proc_address; - - device_priv = NULL; - - ret = av_hwdevice_ctx_init(device_ref); + ret = av_hwdevice_ctx_create(&device_ref, AV_HWDEVICE_TYPE_VDPAU, + ist->hwaccel_device, NULL, 0); if (ret < 0) goto fail; + device_ctx = (AVHWDeviceContext*)device_ref->data; + device_hwctx = device_ctx->hwctx; ctx->hw_frames_ctx = av_hwframe_ctx_alloc(device_ref); if (!ctx->hw_frames_ctx) @@ -198,26 +126,17 @@ do { if (ret < 0) goto fail; - if (av_vdpau_bind_context(s, device, get_proc_address, 0)) + if (av_vdpau_bind_context(s, device_hwctx->device, device_hwctx->get_proc_address, 0)) goto fail; - get_information_string(&vendor); - av_log(NULL, AV_LOG_VERBOSE, "Using VDPAU -- %s -- on X11 display %s, " - "to decode input stream #%d:%d.\n", vendor, - display, ist->file_index, ist->st->index); + av_log(NULL, AV_LOG_VERBOSE, "Using VDPAU to decode input stream #%d:%d.\n", + ist->file_index, ist->st->index); return 0; fail: av_log(NULL, loglevel, "VDPAU init failed for stream #%d:%d.\n", ist->file_index, ist->st->index); - if (device_priv) { - if (device_priv->device_destroy) - device_priv->device_destroy(device); - if (device_priv->dpy) - XCloseDisplay(device_priv->dpy); - } - av_freep(&device_priv); av_buffer_unref(&device_ref); vdpau_uninit(s); return AVERROR(EINVAL); From 18c506e9e6e8df8b1d496d093077b8240ea68c28 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 19 May 2016 19:08:06 +0200 Subject: [PATCH 24/37] avconv_dxva2: use the hwcontext device creation API --- avconv_dxva2.c | 140 ++++--------------------------------------------- 1 file changed, 11 insertions(+), 129 deletions(-) diff --git a/avconv_dxva2.c b/avconv_dxva2.c index a2d6012fa1..186b024cd1 100644 --- a/avconv_dxva2.c +++ b/avconv_dxva2.c @@ -59,9 +59,6 @@ DEFINE_GUID(DXVA2_ModeHEVC_VLD_Main, 0x5b11d51b, 0x2f4c,0x4452,0xbc,0xc3,0x09,0 DEFINE_GUID(DXVA2_NoEncrypt, 0x1b81beD0, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5); DEFINE_GUID(GUID_NULL, 0x00000000, 0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00); -typedef IDirect3D9* WINAPI pDirect3DCreate9(UINT); -typedef HRESULT WINAPI pCreateDeviceManager9(UINT *, IDirect3DDeviceManager9 **); - typedef struct dxva2_mode { const GUID *guid; enum AVCodecID codec; @@ -90,16 +87,6 @@ static const dxva2_mode dxva2_modes[] = { { NULL, 0 }, }; -typedef struct DXVA2DevicePriv { - HMODULE d3dlib; - HMODULE dxva2lib; - - HANDLE deviceHandle; - - IDirect3D9 *d3d9; - IDirect3DDevice9 *d3d9device; -} DXVA2DevicePriv; - typedef struct DXVA2Context { IDirectXVideoDecoder *decoder; @@ -113,32 +100,6 @@ typedef struct DXVA2Context { AVBufferRef *hw_frames_ctx; } DXVA2Context; -static void dxva2_device_uninit(AVHWDeviceContext *ctx) -{ - AVDXVA2DeviceContext *hwctx = ctx->hwctx; - DXVA2DevicePriv *priv = ctx->user_opaque; - - if (hwctx->devmgr && priv->deviceHandle != INVALID_HANDLE_VALUE) - IDirect3DDeviceManager9_CloseDeviceHandle(hwctx->devmgr, priv->deviceHandle); - - if (hwctx->devmgr) - IDirect3DDeviceManager9_Release(hwctx->devmgr); - - if (priv->d3d9device) - IDirect3DDevice9_Release(priv->d3d9device); - - if (priv->d3d9) - IDirect3D9_Release(priv->d3d9); - - if (priv->d3dlib) - FreeLibrary(priv->d3dlib); - - if (priv->dxva2lib) - FreeLibrary(priv->dxva2lib); - - av_freep(&ctx->user_opaque); -} - static void dxva2_uninit(AVCodecContext *s) { InputStream *ist = s->opaque; @@ -195,17 +156,11 @@ static int dxva2_alloc(AVCodecContext *s) InputStream *ist = s->opaque; int loglevel = (ist->hwaccel_id == HWACCEL_AUTO) ? AV_LOG_VERBOSE : AV_LOG_ERROR; DXVA2Context *ctx; - pDirect3DCreate9 *createD3D = NULL; - pCreateDeviceManager9 *createDeviceManager = NULL; + HANDLE device_handle; HRESULT hr; - D3DPRESENT_PARAMETERS d3dpp = {0}; - D3DDISPLAYMODE d3ddm; - unsigned resetToken = 0; - UINT adapter = D3DADAPTER_DEFAULT; AVHWDeviceContext *device_ctx; AVDXVA2DeviceContext *device_hwctx; - DXVA2DevicePriv *device_priv; int ret; ctx = av_mallocz(sizeof(*ctx)); @@ -217,102 +172,29 @@ static int dxva2_alloc(AVCodecContext *s) ist->hwaccel_get_buffer = dxva2_get_buffer; ist->hwaccel_retrieve_data = dxva2_retrieve_data; - ctx->hw_device_ctx = av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_DXVA2); - if (!ctx->hw_device_ctx) + ret = av_hwdevice_ctx_create(&ctx->hw_device_ctx, AV_HWDEVICE_TYPE_DXVA2, + ist->hwaccel_device, NULL, 0); + if (ret < 0) goto fail; - device_ctx = (AVHWDeviceContext*)ctx->hw_device_ctx->data; device_hwctx = device_ctx->hwctx; - device_priv = av_mallocz(sizeof(*device_priv)); - if (!device_priv) - goto fail; - - device_ctx->user_opaque = device_priv; - device_ctx->free = dxva2_device_uninit; - - device_priv->deviceHandle = INVALID_HANDLE_VALUE; - - device_priv->d3dlib = LoadLibrary("d3d9.dll"); - if (!device_priv->d3dlib) { - av_log(NULL, loglevel, "Failed to load D3D9 library\n"); - goto fail; - } - device_priv->dxva2lib = LoadLibrary("dxva2.dll"); - if (!device_priv->dxva2lib) { - av_log(NULL, loglevel, "Failed to load DXVA2 library\n"); - goto fail; - } - - createD3D = (pDirect3DCreate9 *)GetProcAddress(device_priv->d3dlib, "Direct3DCreate9"); - if (!createD3D) { - av_log(NULL, loglevel, "Failed to locate Direct3DCreate9\n"); - goto fail; - } - createDeviceManager = (pCreateDeviceManager9 *)GetProcAddress(device_priv->dxva2lib, "DXVA2CreateDirect3DDeviceManager9"); - if (!createDeviceManager) { - av_log(NULL, loglevel, "Failed to locate DXVA2CreateDirect3DDeviceManager9\n"); - goto fail; - } - - device_priv->d3d9 = createD3D(D3D_SDK_VERSION); - if (!device_priv->d3d9) { - av_log(NULL, loglevel, "Failed to create IDirect3D object\n"); - goto fail; - } - - if (ist->hwaccel_device) { - adapter = atoi(ist->hwaccel_device); - av_log(NULL, AV_LOG_INFO, "Using HWAccel device %d\n", adapter); - } - - IDirect3D9_GetAdapterDisplayMode(device_priv->d3d9, adapter, &d3ddm); - d3dpp.Windowed = TRUE; - d3dpp.BackBufferWidth = 640; - d3dpp.BackBufferHeight = 480; - d3dpp.BackBufferCount = 0; - d3dpp.BackBufferFormat = d3ddm.Format; - d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; - d3dpp.Flags = D3DPRESENTFLAG_VIDEO; - - hr = IDirect3D9_CreateDevice(device_priv->d3d9, adapter, D3DDEVTYPE_HAL, GetShellWindow(), - D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE, - &d3dpp, &device_priv->d3d9device); + hr = IDirect3DDeviceManager9_OpenDeviceHandle(device_hwctx->devmgr, + &device_handle); if (FAILED(hr)) { - av_log(NULL, loglevel, "Failed to create Direct3D device\n"); + av_log(NULL, loglevel, "Failed to open a device handle\n"); goto fail; } - hr = createDeviceManager(&resetToken, &device_hwctx->devmgr); - if (FAILED(hr)) { - av_log(NULL, loglevel, "Failed to create Direct3D device manager\n"); - goto fail; - } - - hr = IDirect3DDeviceManager9_ResetDevice(device_hwctx->devmgr, device_priv->d3d9device, resetToken); - if (FAILED(hr)) { - av_log(NULL, loglevel, "Failed to bind Direct3D device to device manager\n"); - goto fail; - } - - hr = IDirect3DDeviceManager9_OpenDeviceHandle(device_hwctx->devmgr, &device_priv->deviceHandle); - if (FAILED(hr)) { - av_log(NULL, loglevel, "Failed to open device handle\n"); - goto fail; - } - - hr = IDirect3DDeviceManager9_GetVideoService(device_hwctx->devmgr, device_priv->deviceHandle, &IID_IDirectXVideoDecoderService, (void **)&ctx->decoder_service); + hr = IDirect3DDeviceManager9_GetVideoService(device_hwctx->devmgr, device_handle, + &IID_IDirectXVideoDecoderService, + (void **)&ctx->decoder_service); + IDirect3DDeviceManager9_CloseDeviceHandle(device_hwctx->devmgr, device_handle); if (FAILED(hr)) { av_log(NULL, loglevel, "Failed to create IDirectXVideoDecoderService\n"); goto fail; } - ret = av_hwdevice_ctx_init(ctx->hw_device_ctx); - if (ret < 0) { - av_log(NULL, loglevel, "Failed to initialize the HW device context\n"); - goto fail; - } - ctx->tmp_frame = av_frame_alloc(); if (!ctx->tmp_frame) goto fail; From 9f7590f4e497c12693247d7f935a20d7773a64dd Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 19 May 2016 19:08:06 +0200 Subject: [PATCH 25/37] avconv_vaapi: use the hwcontext device creation API --- avconv_vaapi.c | 96 +++----------------------------------------------- 1 file changed, 4 insertions(+), 92 deletions(-) diff --git a/avconv_vaapi.c b/avconv_vaapi.c index 36b34e8cda..ddee72c53f 100644 --- a/avconv_vaapi.c +++ b/avconv_vaapi.c @@ -523,102 +523,14 @@ fail: static AVClass *vaapi_log = &vaapi_class; -static av_cold void vaapi_device_uninit(AVHWDeviceContext *hwdev) -{ - AVVAAPIDeviceContext *hwctx = hwdev->hwctx; - av_log(&vaapi_log, AV_LOG_VERBOSE, "Terminating VAAPI connection.\n"); - vaTerminate(hwctx->display); -} - av_cold int vaapi_device_init(const char *device) { - AVHWDeviceContext *hwdev; - AVVAAPIDeviceContext *hwctx; - VADisplay display; - VAStatus vas; - int major, minor, err; + int err; - display = 0; - -#if HAVE_VAAPI_X11 - if (!display) { - Display *x11_display; - - // Try to open the device as an X11 display. - x11_display = XOpenDisplay(device); - if (!x11_display) { - av_log(&vaapi_log, AV_LOG_WARNING, "Cannot open X11 display " - "%s.\n", XDisplayName(device)); - } else { - display = vaGetDisplay(x11_display); - if (!display) { - av_log(&vaapi_log, AV_LOG_WARNING, "Cannot open a VA display " - "from X11 display %s.\n", XDisplayName(device)); - XCloseDisplay(x11_display); - } else { - av_log(&vaapi_log, AV_LOG_VERBOSE, "Opened VA display via " - "X11 display %s.\n", XDisplayName(device)); - } - } - } -#endif - -#if HAVE_VAAPI_DRM - if (!display && device) { - int drm_fd; - - // Try to open the device as a DRM path. - drm_fd = open(device, O_RDWR); - if (drm_fd < 0) { - av_log(&vaapi_log, AV_LOG_WARNING, "Cannot open DRM device %s.\n", - device); - } else { - display = vaGetDisplayDRM(drm_fd); - if (!display) { - av_log(&vaapi_log, AV_LOG_WARNING, "Cannot open a VA display " - "from DRM device %s.\n", device); - close(drm_fd); - } else { - av_log(&vaapi_log, AV_LOG_VERBOSE, "Opened VA display via " - "DRM device %s.\n", device); - } - } - } -#endif - - if (!display) { - av_log(&vaapi_log, AV_LOG_ERROR, "No VA display found for " - "device %s.\n", device); - return AVERROR(EINVAL); - } - - vas = vaInitialize(display, &major, &minor); - if (vas != VA_STATUS_SUCCESS) { - av_log(&vaapi_log, AV_LOG_ERROR, "Failed to initialise VAAPI " - "connection: %d (%s).\n", vas, vaErrorStr(vas)); - return AVERROR(EIO); - } - av_log(&vaapi_log, AV_LOG_VERBOSE, "Initialised VAAPI connection: " - "version %d.%d\n", major, minor); - - hw_device_ctx = av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_VAAPI); - if (!hw_device_ctx) { - av_log(&vaapi_log, AV_LOG_ERROR, "Failed to create VAAPI " - "hardware context.\n"); - vaTerminate(display); - return AVERROR(ENOMEM); - } - - hwdev = (AVHWDeviceContext*)hw_device_ctx->data; - hwdev->free = &vaapi_device_uninit; - - hwctx = hwdev->hwctx; - hwctx->display = display; - - err = av_hwdevice_ctx_init(hw_device_ctx); + err = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_VAAPI, + device, NULL, 0); if (err < 0) { - av_log(&vaapi_log, AV_LOG_ERROR, "Failed to initialise VAAPI " - "hardware context: %d\n", err); + av_log(&vaapi_log, AV_LOG_ERROR, "Failed to create a VAAPI device\n"); return err; } From 80fb19bc234a3f2350d891adf39f3738a8e4849f Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 24 May 2016 16:36:16 +0200 Subject: [PATCH 26/37] avconv: fix a check for av_bsf_get_by_name() return value --- avconv_opt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/avconv_opt.c b/avconv_opt.c index d73df67e97..c02e4798e6 100644 --- a/avconv_opt.c +++ b/avconv_opt.c @@ -1015,7 +1015,7 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e *next++ = 0; filter = av_bsf_get_by_name(bsf); - if (!bsf) { + if (!filter) { av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf); exit_program(1); } From fe7b21c8f148493c6fbceb7f887a77531dd1ae0e Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 24 May 2016 16:49:19 +0200 Subject: [PATCH 27/37] avconv: fix parsing bitstream filters The current code modifies the user-supplied string, which is shared for the whole output file. So a bitstream filter specification applied to multiple streams would not work correctly. --- avconv_opt.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/avconv_opt.c b/avconv_opt.c index c02e4798e6..b760a18b8f 100644 --- a/avconv_opt.c +++ b/avconv_opt.c @@ -941,7 +941,8 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e OutputStream *ost; AVStream *st = avformat_new_stream(oc, NULL); int idx = oc->nb_streams - 1, ret = 0; - char *bsf = NULL, *next, *codec_tag = NULL; + const char *bsfs = NULL; + char *next, *codec_tag = NULL; double qscale = -1; if (!st) { @@ -1007,18 +1008,21 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e ost->max_frames = INT64_MAX; MATCH_PER_STREAM_OPT(max_frames, i64, ost->max_frames, oc, st); - MATCH_PER_STREAM_OPT(bitstream_filters, str, bsf, oc, st); - while (bsf) { + MATCH_PER_STREAM_OPT(bitstream_filters, str, bsfs, oc, st); + while (bsfs && *bsfs) { const AVBitStreamFilter *filter; + char *bsf; - if (next = strchr(bsf, ',')) - *next++ = 0; + bsf = av_get_token(&bsfs, ","); + if (!bsf) + exit_program(1); filter = av_bsf_get_by_name(bsf); if (!filter) { av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf); exit_program(1); } + av_freep(&bsf); ost->bitstream_filters = av_realloc_array(ost->bitstream_filters, ost->nb_bitstream_filters + 1, @@ -1027,8 +1031,8 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e exit_program(1); ost->bitstream_filters[ost->nb_bitstream_filters++] = filter; - - bsf = next; + if (*bsfs) + bsfs++; } MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, oc, st); From f5c43884190be094749acfba104e3eab98d8ff1e Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 24 May 2016 22:20:45 +0200 Subject: [PATCH 28/37] FATE: drop the audio stream from the dxtory test This is a video test and there are no audio packets in the sample anyway. --- tests/fate/screen.mak | 2 +- tests/ref/fate/dxtory | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/fate/screen.mak b/tests/fate/screen.mak index 9d0fb0f977..7e91f19d12 100644 --- a/tests/fate/screen.mak +++ b/tests/fate/screen.mak @@ -3,7 +3,7 @@ FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, CSCD) += fate-cscd fate-cscd: CMD = framecrc -i $(TARGET_SAMPLES)/CSCD/sample_video.avi -an -pix_fmt rgb24 FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, DXTORY) += fate-dxtory -fate-dxtory: CMD = framecrc -i $(TARGET_SAMPLES)/dxtory/dxtory_mic.avi +fate-dxtory: CMD = framecrc -i $(TARGET_SAMPLES)/dxtory/dxtory_mic.avi -an FATE_SAMPLES_AVCONV-$(call DEMDEC, AVI, FIC) += fate-fic-avi fate-fic-avi: CMD = framecrc -i $(TARGET_SAMPLES)/fic/fic-partial-2MB.avi -an diff --git a/tests/ref/fate/dxtory b/tests/ref/fate/dxtory index 7d3ecbdf0e..8cee5efaca 100644 --- a/tests/ref/fate/dxtory +++ b/tests/ref/fate/dxtory @@ -1,3 +1,2 @@ #tb 0: 1/25 -#tb 1: 1/48000 0, 0, 0, 1, 1382400, 0x44373645 From 6641819feedb086ebba3d2be89b8d33980f367e1 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 24 May 2016 12:16:52 +0200 Subject: [PATCH 29/37] build: Ignore generated mapfile and remove it on distclean --- .gitignore | 1 + Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 5464bba7e6..e71246c724 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,4 @@ /config.* /coverage.info /lcov/ +/mapfile diff --git a/Makefile b/Makefile index 1d7bc4a470..1f7970553a 100644 --- a/Makefile +++ b/Makefile @@ -218,7 +218,7 @@ clean:: distclean:: $(RM) $(DISTCLEANSUFFIXES) $(RM) config.* .config libavutil/avconfig.h .version avversion.h \ - libavcodec/bsf_list.c libavformat/protocol_list.c + mapfile libavcodec/bsf_list.c libavformat/protocol_list.c config: $(SRC_PATH)/configure $(value LIBAV_CONFIGURATION) From 2bfa067d0b636e7b2004fb0ad5a53d0d48c6de32 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Wed, 18 May 2016 10:58:56 +0100 Subject: [PATCH 30/37] vaapi_encode: Check config attributes before creating config This prevents attempts to use unsupported modes, such as low-power H.264 mode on non-Skylake targets. Also fixes a crash on invalid configuration, when trying to destroy an invalid VA config/context. --- libavcodec/vaapi_encode.c | 132 +++++++++++++++++++++++++++++++++++++- 1 file changed, 130 insertions(+), 2 deletions(-) diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c index 075c848f60..9da55c97fd 100644 --- a/libavcodec/vaapi_encode.c +++ b/libavcodec/vaapi_encode.c @@ -20,6 +20,7 @@ #include #include "libavutil/avassert.h" +#include "libavutil/common.h" #include "libavutil/log.h" #include "libavutil/pixdesc.h" @@ -887,6 +888,122 @@ fail: return err; } +static av_cold int vaapi_encode_check_config(AVCodecContext *avctx) +{ + VAAPIEncodeContext *ctx = avctx->priv_data; + VAStatus vas; + int i, n, err; + VAProfile *profiles = NULL; + VAEntrypoint *entrypoints = NULL; + VAConfigAttrib attr[] = { + { VAConfigAttribRateControl }, + { VAConfigAttribEncMaxRefFrames }, + }; + + n = vaMaxNumProfiles(ctx->hwctx->display); + profiles = av_malloc_array(n, sizeof(VAProfile)); + if (!profiles) { + err = AVERROR(ENOMEM); + goto fail; + } + vas = vaQueryConfigProfiles(ctx->hwctx->display, profiles, &n); + if (vas != VA_STATUS_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Failed to query profiles: %d (%s).\n", + vas, vaErrorStr(vas)); + err = AVERROR(ENOSYS); + goto fail; + } + for (i = 0; i < n; i++) { + if (profiles[i] == ctx->va_profile) + break; + } + if (i >= n) { + av_log(ctx, AV_LOG_ERROR, "Encoding profile not found (%d).\n", + ctx->va_profile); + err = AVERROR(ENOSYS); + goto fail; + } + + n = vaMaxNumEntrypoints(ctx->hwctx->display); + entrypoints = av_malloc_array(n, sizeof(VAEntrypoint)); + if (!entrypoints) { + err = AVERROR(ENOMEM); + goto fail; + } + vas = vaQueryConfigEntrypoints(ctx->hwctx->display, ctx->va_profile, + entrypoints, &n); + if (vas != VA_STATUS_SUCCESS) { + av_log(ctx, AV_LOG_ERROR, "Failed to query entrypoints for " + "profile %u: %d (%s).\n", ctx->va_profile, + vas, vaErrorStr(vas)); + err = AVERROR(ENOSYS); + goto fail; + } + for (i = 0; i < n; i++) { + if (entrypoints[i] == ctx->va_entrypoint) + break; + } + if (i >= n) { + av_log(ctx, AV_LOG_ERROR, "Encoding entrypoint not found " + "(%d / %d).\n", ctx->va_profile, ctx->va_entrypoint); + err = AVERROR(ENOSYS); + goto fail; + } + + vas = vaGetConfigAttributes(ctx->hwctx->display, + ctx->va_profile, ctx->va_entrypoint, + attr, FF_ARRAY_ELEMS(attr)); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to fetch config " + "attributes: %d (%s).\n", vas, vaErrorStr(vas)); + return AVERROR(EINVAL); + } + + for (i = 0; i < FF_ARRAY_ELEMS(attr); i++) { + if (attr[i].value == VA_ATTRIB_NOT_SUPPORTED) { + // Unfortunately we have to treat this as "don't know" and hope + // for the best, because the Intel MJPEG encoder returns this + // for all the interesting attributes. + continue; + } + switch (attr[i].type) { + case VAConfigAttribRateControl: + if (!(ctx->va_rc_mode & attr[i].value)) { + av_log(avctx, AV_LOG_ERROR, "Rate control mode is not " + "supported: %x\n", attr[i].value); + err = AVERROR(EINVAL); + goto fail; + } + break; + case VAConfigAttribEncMaxRefFrames: + { + unsigned int ref_l0 = attr[i].value & 0xffff; + unsigned int ref_l1 = (attr[i].value >> 16) & 0xffff; + + if (avctx->gop_size > 1 && ref_l0 < 1) { + av_log(avctx, AV_LOG_ERROR, "P frames are not " + "supported (%x).\n", attr[i].value); + err = AVERROR(EINVAL); + goto fail; + } + if (avctx->max_b_frames > 0 && ref_l1 < 1) { + av_log(avctx, AV_LOG_ERROR, "B frames are not " + "supported (%x).\n", attr[i].value); + err = AVERROR(EINVAL); + goto fail; + } + } + break; + } + } + + err = 0; +fail: + av_freep(&profiles); + av_freep(&entrypoints); + return err; +} + av_cold int ff_vaapi_encode_init(AVCodecContext *avctx, const VAAPIEncodeType *type) { @@ -907,6 +1024,9 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx, ctx->codec = type; ctx->codec_options = ctx->codec_options_data; + ctx->va_config = VA_INVALID_ID; + ctx->va_context = VA_INVALID_ID; + ctx->priv_data = av_mallocz(type->priv_data_size); if (!ctx->priv_data) { err = AVERROR(ENOMEM); @@ -932,6 +1052,10 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx, if (err < 0) goto fail; + err = vaapi_encode_check_config(avctx); + if (err < 0) + goto fail; + vas = vaCreateConfig(ctx->hwctx->display, ctx->va_profile, ctx->va_entrypoint, ctx->config_attributes, ctx->nb_config_attributes, @@ -1088,11 +1212,15 @@ av_cold int ff_vaapi_encode_close(AVCodecContext *avctx) vaapi_encode_free(avctx, pic); } - if (ctx->va_context != VA_INVALID_ID) + if (ctx->va_context != VA_INVALID_ID) { vaDestroyContext(ctx->hwctx->display, ctx->va_context); + ctx->va_context = VA_INVALID_ID; + } - if (ctx->va_config != VA_INVALID_ID) + if (ctx->va_config != VA_INVALID_ID) { vaDestroyConfig(ctx->hwctx->display, ctx->va_config); + ctx->va_config = VA_INVALID_ID; + } if (ctx->codec->close) ctx->codec->close(avctx); From b51c7c6b8a5b35cfd06cb9655f9ec4c9f0ddd81b Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Mon, 16 May 2016 14:01:31 +0100 Subject: [PATCH 31/37] vaapi_h264: Fix frame_num after non-reference frames Non-reference frames (nal_ref_idc == 0) should be discardable, so frame_num does not advance after them. Before this change, a stream containing unreferenced B-frames would be rejected by the reference decoder. --- libavcodec/vaapi_encode_h264.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c index 8690a8565b..7819788cf7 100644 --- a/libavcodec/vaapi_encode_h264.c +++ b/libavcodec/vaapi_encode_h264.c @@ -101,8 +101,8 @@ typedef struct VAAPIEncodeH264Context { int fixed_qp_p; int fixed_qp_b; + int next_frame_num; int64_t idr_pic_count; - int64_t last_idr_frame; // Rate control configuration. struct { @@ -592,12 +592,17 @@ static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx, if (pic->type == PICTURE_TYPE_IDR) { av_assert0(pic->display_order == pic->encode_order); - priv->last_idr_frame = pic->display_order; + vpic->frame_num = 0; + priv->next_frame_num = 1; } else { - av_assert0(pic->display_order > priv->last_idr_frame); + vpic->frame_num = priv->next_frame_num; + if (pic->type != PICTURE_TYPE_B) { + // nal_ref_idc != 0 + ++priv->next_frame_num; + } } - vpic->frame_num = (pic->encode_order - priv->last_idr_frame) & + vpic->frame_num = vpic->frame_num & ((1 << (4 + vseq->seq_fields.bits.log2_max_frame_num_minus4)) - 1); vpic->CurrPic.picture_id = pic->recon_surface; @@ -608,10 +613,9 @@ static int vaapi_encode_h264_init_picture_params(AVCodecContext *avctx, for (i = 0; i < pic->nb_refs; i++) { VAAPIEncodePicture *ref = pic->refs[i]; - av_assert0(ref && ref->encode_order >= priv->last_idr_frame); + av_assert0(ref && ref->encode_order < pic->encode_order); vpic->ReferenceFrames[i].picture_id = ref->recon_surface; - vpic->ReferenceFrames[i].frame_idx = - ref->encode_order - priv->last_idr_frame; + vpic->ReferenceFrames[i].frame_idx = ref->encode_order; vpic->ReferenceFrames[i].flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE; vpic->ReferenceFrames[i].TopFieldOrderCnt = ref->display_order; vpic->ReferenceFrames[i].BottomFieldOrderCnt = ref->display_order; From a86aa16088ad7f22a8918d71adb8c040d6033d84 Mon Sep 17 00:00:00 2001 From: Mark Thompson Date: Tue, 17 May 2016 23:08:57 +0100 Subject: [PATCH 32/37] vaapi_h264: Add trivial support for low-power encoding Experimental; requires Skylake and VAAPI 0.39.1 (not yet released). Also increases the allowed range of the quality option - in low-power mode, the Intel driver supports levels 1-8 (and 0 meaning default). --- libavcodec/vaapi_encode_h264.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c index 7819788cf7..2341b123fc 100644 --- a/libavcodec/vaapi_encode_h264.c +++ b/libavcodec/vaapi_encode_h264.c @@ -126,6 +126,7 @@ typedef struct VAAPIEncodeH264Context { typedef struct VAAPIEncodeH264Options { int qp; int quality; + int low_power; } VAAPIEncodeH264Options; @@ -854,7 +855,17 @@ static av_cold int vaapi_encode_h264_init_internal(AVCodecContext *avctx) avctx->profile); return AVERROR(EINVAL); } - ctx->va_entrypoint = VAEntrypointEncSlice; + if (opt->low_power) { +#if VA_CHECK_VERSION(0, 39, 1) + ctx->va_entrypoint = VAEntrypointEncSliceLP; +#else + av_log(avctx, AV_LOG_ERROR, "Low-power encoding is not " + "supported with this VAAPI version.\n"); + return AVERROR(EINVAL); +#endif + } else { + ctx->va_entrypoint = VAEntrypointEncSlice; + } ctx->input_width = avctx->width; ctx->input_height = avctx->height; @@ -937,7 +948,10 @@ static const AVOption vaapi_encode_h264_options[] = { { "qp", "Constant QP (for P-frames; scaled by qfactor/qoffset for I/B)", OFFSET(qp), AV_OPT_TYPE_INT, { .i64 = 20 }, 0, 52, FLAGS }, { "quality", "Set encode quality (trades off against speed, higher is faster)", - OFFSET(quality), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, FLAGS }, + OFFSET(quality), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 8, FLAGS }, + { "low_power", "Use low-power encoding mode (experimental: only supported " + "on some platforms, does not support all features)", + OFFSET(low_power), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS }, { NULL }, }; From 5264e7ba217b3c0ceae813917134e1ab52573141 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Thu, 26 May 2016 02:41:25 +0200 Subject: [PATCH 33/37] ac3: Check the array bound before dereferencing CC: libav-stable@libav.org Signed-off-by: Luca Barbato --- libavcodec/ac3enc_template.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/ac3enc_template.c b/libavcodec/ac3enc_template.c index 8febf858ef..ec8ec4ef6a 100644 --- a/libavcodec/ac3enc_template.c +++ b/libavcodec/ac3enc_template.c @@ -260,7 +260,7 @@ static void apply_channel_coupling(AC3EncodeContext *s) energy_cpl = energy[blk][CPL_CH][bnd]; energy_ch = energy[blk][ch][bnd]; blk1 = blk+1; - while (!s->blocks[blk1].new_cpl_coords[ch] && blk1 < s->num_blocks) { + while (blk1 < s->num_blocks && !s->blocks[blk1].new_cpl_coords[ch]) { if (s->blocks[blk1].cpl_in_use) { energy_cpl += energy[blk1][CPL_CH][bnd]; energy_ch += energy[blk1][ch][bnd]; From dc40a70c5755bccfb1a1349639943e1f408bea50 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Tue, 24 May 2016 20:06:03 +0200 Subject: [PATCH 34/37] Drop unnecessary libavutil/x86/asm.h #includes --- libavcodec/msmpeg4dec.c | 1 - libavcodec/x86/audiodsp_init.c | 1 - libavcodec/x86/fmtconvert_init.c | 1 - libavcodec/x86/hpeldsp_init.c | 1 - libavcodec/x86/mpegvideodsp.c | 1 - libavcodec/x86/rv34dsp_init.c | 1 - libavcodec/x86/vp6dsp_init.c | 1 - libavcodec/x86/vp8dsp_init.c | 1 - libavcodec/x86/vp9dsp_init.c | 1 - libavfilter/x86/vf_gradfun_init.c | 1 - libavfilter/x86/vf_interlace_init.c | 1 - libavfilter/x86/vf_yadif_init.c | 1 - libswscale/x86/rgb2rgb.c | 1 - libswscale/x86/swscale.c | 1 - 14 files changed, 14 deletions(-) diff --git a/libavcodec/msmpeg4dec.c b/libavcodec/msmpeg4dec.c index 1c55558545..7c22b375d9 100644 --- a/libavcodec/msmpeg4dec.c +++ b/libavcodec/msmpeg4dec.c @@ -27,7 +27,6 @@ #include "mpegutils.h" #include "mpegvideo.h" #include "msmpeg4.h" -#include "libavutil/x86/asm.h" #include "h263.h" #include "mpeg4video.h" #include "msmpeg4data.h" diff --git a/libavcodec/x86/audiodsp_init.c b/libavcodec/x86/audiodsp_init.c index 743f5a3699..8eb2e56bdd 100644 --- a/libavcodec/x86/audiodsp_init.c +++ b/libavcodec/x86/audiodsp_init.c @@ -21,7 +21,6 @@ #include "config.h" #include "libavutil/attributes.h" #include "libavutil/cpu.h" -#include "libavutil/x86/asm.h" #include "libavutil/x86/cpu.h" #include "libavcodec/audiodsp.h" #include "audiodsp.h" diff --git a/libavcodec/x86/fmtconvert_init.c b/libavcodec/x86/fmtconvert_init.c index 1871b477bb..2f10db4fc1 100644 --- a/libavcodec/x86/fmtconvert_init.c +++ b/libavcodec/x86/fmtconvert_init.c @@ -24,7 +24,6 @@ #include "libavutil/attributes.h" #include "libavutil/cpu.h" -#include "libavutil/x86/asm.h" #include "libavutil/x86/cpu.h" #include "libavcodec/fmtconvert.h" diff --git a/libavcodec/x86/hpeldsp_init.c b/libavcodec/x86/hpeldsp_init.c index 59cb5e143a..65aac7164d 100644 --- a/libavcodec/x86/hpeldsp_init.c +++ b/libavcodec/x86/hpeldsp_init.c @@ -24,7 +24,6 @@ #include "libavutil/attributes.h" #include "libavutil/cpu.h" -#include "libavutil/x86/asm.h" #include "libavutil/x86/cpu.h" #include "libavcodec/avcodec.h" #include "libavcodec/hpeldsp.h" diff --git a/libavcodec/x86/mpegvideodsp.c b/libavcodec/x86/mpegvideodsp.c index 0e5dd0f153..b701ef8cc7 100644 --- a/libavcodec/x86/mpegvideodsp.c +++ b/libavcodec/x86/mpegvideodsp.c @@ -19,7 +19,6 @@ #include "config.h" #include "libavutil/attributes.h" #include "libavutil/cpu.h" -#include "libavutil/x86/asm.h" #include "libavutil/x86/cpu.h" #include "libavcodec/mpegvideodsp.h" diff --git a/libavcodec/x86/rv34dsp_init.c b/libavcodec/x86/rv34dsp_init.c index 586e4e9a6d..32d4c1aac2 100644 --- a/libavcodec/x86/rv34dsp_init.c +++ b/libavcodec/x86/rv34dsp_init.c @@ -21,7 +21,6 @@ #include "libavutil/attributes.h" #include "libavutil/cpu.h" -#include "libavutil/x86/asm.h" #include "libavutil/x86/cpu.h" #include "libavcodec/rv34dsp.h" diff --git a/libavcodec/x86/vp6dsp_init.c b/libavcodec/x86/vp6dsp_init.c index cd94f3e038..9bf41783c2 100644 --- a/libavcodec/x86/vp6dsp_init.c +++ b/libavcodec/x86/vp6dsp_init.c @@ -22,7 +22,6 @@ #include "libavutil/attributes.h" #include "libavutil/cpu.h" -#include "libavutil/x86/asm.h" #include "libavutil/x86/cpu.h" #include "libavcodec/vp56dsp.h" diff --git a/libavcodec/x86/vp8dsp_init.c b/libavcodec/x86/vp8dsp_init.c index e5afd493bb..8f6d43ce16 100644 --- a/libavcodec/x86/vp8dsp_init.c +++ b/libavcodec/x86/vp8dsp_init.c @@ -23,7 +23,6 @@ #include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/mem.h" -#include "libavutil/x86/asm.h" #include "libavutil/x86/cpu.h" #include "libavcodec/vp8dsp.h" diff --git a/libavcodec/x86/vp9dsp_init.c b/libavcodec/x86/vp9dsp_init.c index ce58c08a3b..833d983ab1 100644 --- a/libavcodec/x86/vp9dsp_init.c +++ b/libavcodec/x86/vp9dsp_init.c @@ -24,7 +24,6 @@ #include "libavutil/cpu.h" #include "libavutil/internal.h" #include "libavutil/mem.h" -#include "libavutil/x86/asm.h" #include "libavutil/x86/cpu.h" #include "libavcodec/vp9.h" diff --git a/libavfilter/x86/vf_gradfun_init.c b/libavfilter/x86/vf_gradfun_init.c index 3f23bf6799..f8d85c7120 100644 --- a/libavfilter/x86/vf_gradfun_init.c +++ b/libavfilter/x86/vf_gradfun_init.c @@ -22,7 +22,6 @@ #include "libavutil/attributes.h" #include "libavutil/cpu.h" #include "libavutil/mem.h" -#include "libavutil/x86/asm.h" #include "libavutil/x86/cpu.h" #include "libavfilter/gradfun.h" diff --git a/libavfilter/x86/vf_interlace_init.c b/libavfilter/x86/vf_interlace_init.c index 231ab85a1c..105eeb6920 100644 --- a/libavfilter/x86/vf_interlace_init.c +++ b/libavfilter/x86/vf_interlace_init.c @@ -22,7 +22,6 @@ #include "libavutil/cpu.h" #include "libavutil/internal.h" #include "libavutil/mem.h" -#include "libavutil/x86/asm.h" #include "libavutil/x86/cpu.h" #include "libavfilter/interlace.h" diff --git a/libavfilter/x86/vf_yadif_init.c b/libavfilter/x86/vf_yadif_init.c index 510a02394c..863e7df87b 100644 --- a/libavfilter/x86/vf_yadif_init.c +++ b/libavfilter/x86/vf_yadif_init.c @@ -22,7 +22,6 @@ #include "libavutil/cpu.h" #include "libavutil/internal.h" #include "libavutil/mem.h" -#include "libavutil/x86/asm.h" #include "libavutil/x86/cpu.h" #include "libavfilter/yadif.h" diff --git a/libswscale/x86/rgb2rgb.c b/libswscale/x86/rgb2rgb.c index 9cfe831e3c..4dcd87c4ae 100644 --- a/libswscale/x86/rgb2rgb.c +++ b/libswscale/x86/rgb2rgb.c @@ -27,7 +27,6 @@ #include "config.h" #include "libavutil/attributes.h" -#include "libavutil/x86/asm.h" #include "libavutil/x86/cpu.h" #include "libavutil/cpu.h" #include "libavutil/bswap.h" diff --git a/libswscale/x86/swscale.c b/libswscale/x86/swscale.c index f310a7593f..ec774678d5 100644 --- a/libswscale/x86/swscale.c +++ b/libswscale/x86/swscale.c @@ -24,7 +24,6 @@ #include "libswscale/swscale_internal.h" #include "libavutil/attributes.h" #include "libavutil/intreadwrite.h" -#include "libavutil/x86/asm.h" #include "libavutil/x86/cpu.h" #include "libavutil/cpu.h" #include "libavutil/pixdesc.h" From 8fb92ea7e2a60c7f428136eb0d3d80810c1c74fc Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Mon, 13 Jun 2016 12:17:44 +0200 Subject: [PATCH 35/37] avcodec: add YUY2 Lossless Codec decoder Signed-off-by: Paul B Mahol --- Changelog | 4 + libavcodec/Makefile | 1 + libavcodec/allcodecs.c | 1 + libavcodec/avcodec.h | 1 + libavcodec/codec_desc.c | 7 + libavcodec/version.h | 2 +- libavcodec/ylc.c | 472 ++++++++++++++++++++++++++++++++++++++++ libavformat/riff.c | 1 + 8 files changed, 488 insertions(+), 1 deletion(-) create mode 100644 libavcodec/ylc.c diff --git a/Changelog b/Changelog index aabdf9050a..99cfa12a3a 100644 --- a/Changelog +++ b/Changelog @@ -2,6 +2,10 @@ Entries are sorted chronologically from oldest to youngest within each release, releases are sorted from youngest to oldest. version : +- YUY2 Lossless Codec decoder + + +version 3.1: - DXVA2-accelerated HEVC Main10 decoding - fieldhint filter - loop video filter and aloop audio filter diff --git a/libavcodec/Makefile b/libavcodec/Makefile index a251845515..fd0d1f0afc 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -633,6 +633,7 @@ OBJS-$(CONFIG_XWD_DECODER) += xwddec.o OBJS-$(CONFIG_XWD_ENCODER) += xwdenc.o OBJS-$(CONFIG_Y41P_DECODER) += y41pdec.o OBJS-$(CONFIG_Y41P_ENCODER) += y41penc.o +OBJS-$(CONFIG_YLC_DECODER) += ylc.o OBJS-$(CONFIG_YOP_DECODER) += yop.o OBJS-$(CONFIG_YUV4_DECODER) += yuv4dec.o OBJS-$(CONFIG_YUV4_ENCODER) += yuv4enc.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 02fc834e6f..54efaad344 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -370,6 +370,7 @@ void avcodec_register_all(void) REGISTER_DECODER(XL, xl); REGISTER_ENCDEC (XWD, xwd); REGISTER_ENCDEC (Y41P, y41p); + REGISTER_DECODER(YLC, ylc); REGISTER_DECODER(YOP, yop); REGISTER_ENCDEC (YUV4, yuv4); REGISTER_DECODER(ZERO12V, zero12v); diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index e3c9bcb0d8..c8a4039fe4 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -408,6 +408,7 @@ enum AVCodecID { AV_CODEC_ID_M101, AV_CODEC_ID_MAGICYUV, AV_CODEC_ID_SHEERVIDEO, + AV_CODEC_ID_YLC, /* various PCM "codecs" */ AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 575a6e5910..9d94b72ed2 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -1556,6 +1556,13 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("BitJazz SheerVideo"), .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, }, + { + .id = AV_CODEC_ID_YLC, + .type = AVMEDIA_TYPE_VIDEO, + .name = "ylc", + .long_name = NULL_IF_CONFIG_SMALL("YUY2 Lossless Codec"), + .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, + }, /* various PCM "codecs" */ { diff --git a/libavcodec/version.h b/libavcodec/version.h index 000026e1a5..f7cbae962f 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 57 -#define LIBAVCODEC_VERSION_MINOR 47 +#define LIBAVCODEC_VERSION_MINOR 48 #define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ diff --git a/libavcodec/ylc.c b/libavcodec/ylc.c new file mode 100644 index 0000000000..95a5e05baa --- /dev/null +++ b/libavcodec/ylc.c @@ -0,0 +1,472 @@ +/* + * YUY2 Lossless Codec + * + * 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 +#include +#include + +#include "libavutil/imgutils.h" +#include "libavutil/internal.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/mem.h" +#include "avcodec.h" +#include "bswapdsp.h" +#include "get_bits.h" +#include "huffyuvdsp.h" +#include "internal.h" +#include "unary.h" + +typedef struct YLCContext { + VLC vlc[4]; + uint32_t table[1024]; + uint8_t *table_bits; + uint8_t *bitstream_bits; + int table_bits_size; + int bitstream_bits_size; + BswapDSPContext bdsp; +} YLCContext; + +static av_cold int decode_init(AVCodecContext *avctx) +{ + YLCContext *s = avctx->priv_data; + + avctx->pix_fmt = AV_PIX_FMT_YUYV422; + ff_bswapdsp_init(&s->bdsp); + + return 0; +} + +typedef struct Node { + int16_t sym; + int16_t n0; + uint32_t count; + int16_t l, r; +} Node; + +static void get_tree_codes(uint32_t *bits, int16_t *lens, uint8_t *xlat, + Node *nodes, int node, + uint32_t pfx, int pl, int *pos) +{ + int s; + + s = nodes[node].sym; + if (s != -1) { + bits[*pos] = (~pfx) & ((1 << FFMAX(pl, 1)) - 1); + lens[*pos] = FFMAX(pl, 1); + xlat[*pos] = s + (pl == 0); + (*pos)++; + } else { + pfx <<= 1; + pl++; + get_tree_codes(bits, lens, xlat, nodes, nodes[node].l, pfx, pl, + pos); + pfx |= 1; + get_tree_codes(bits, lens, xlat, nodes, nodes[node].r, pfx, pl, + pos); + } +} + +static int build_vlc(AVCodecContext *avctx, VLC *vlc, const uint32_t *table) +{ + Node nodes[512]; + uint32_t bits[256]; + int16_t lens[256]; + uint8_t xlat[256]; + int cur_node, i, j, pos = 0; + + ff_free_vlc(vlc); + + for (i = 0; i < 256; i++) { + nodes[i].count = table[i]; + nodes[i].sym = i; + nodes[i].n0 = -2; + nodes[i].l = i; + nodes[i].r = i; + } + + cur_node = 256; + j = 0; + do { + for (i = 0; ; i++) { + int new_node = j; + int first_node = cur_node; + int second_node = cur_node; + int nd, st; + + nodes[cur_node].count = -1; + + do { + int val = nodes[new_node].count; + if (val && (val < nodes[first_node].count)) { + if (val >= nodes[second_node].count) { + first_node = new_node; + } else { + first_node = second_node; + second_node = new_node; + } + } + new_node += 1; + } while (new_node != cur_node); + + if (first_node == cur_node) + break; + + nd = nodes[second_node].count; + st = nodes[first_node].count; + nodes[second_node].count = 0; + nodes[first_node].count = 0; + nodes[cur_node].count = nd + st; + nodes[cur_node].sym = -1; + nodes[cur_node].n0 = cur_node; + nodes[cur_node].l = first_node; + nodes[cur_node].r = second_node; + cur_node++; + } + j++; + } while (cur_node - 256 == j); + + get_tree_codes(bits, lens, xlat, nodes, cur_node - 1, 0, 0, &pos); + + return ff_init_vlc_sparse(vlc, 10, pos, lens, 2, 2, bits, 4, 4, xlat, 1, 1, 0); +} + +static const uint8_t table_y1[] = { + 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, + 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, + 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, + 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, + 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, + 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x00, +}; + +static const uint8_t table_u[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x00, +}; + +static const uint8_t table_y2[] = { + 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, + 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFC, + 0xFC, 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFC, 0xFC, + 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFD, 0xFD, 0xFD, + 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x01, 0x01, 0x01, 0xFD, 0xFD, 0xFD, 0xFE, + 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, + 0x01, 0x01, 0x01, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, + 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, + 0x01, 0x01, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, + 0x02, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, + 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, + 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0x00, 0x00, + 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0xFF, + 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, + 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0xFF, 0xFF, + 0xFF, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, + 0x02, 0x02, 0x03, 0x03, 0x03, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, + 0x02, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x01, + 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, + 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, + 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, + 0x04, 0x04, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, + 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, + 0x04, 0x00, +}; + +static const uint8_t table_v[] = { + 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, + 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, + 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, + 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, + 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, + 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, + 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, + 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, + 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, + 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, + 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, + 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, + 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, + 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, + 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, + 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, + 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, + 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, + 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, + 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, + 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, + 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, + 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, + 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, + 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, + 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, + 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, + 0xFF, 0x00, 0x01, 0xFF, 0x00, 0x01, 0xFF, 0x00, + 0x01, 0x00, +}; + +static int decode_frame(AVCodecContext *avctx, + void *data, int *got_frame, + AVPacket *avpkt) +{ + int TL[4] = { 128, 128, 128, 128 }; + int L[4] = { 128, 128, 128, 128 }; + YLCContext *s = avctx->priv_data; + const uint8_t *buf = avpkt->data; + int ret, x, y, toffset, boffset; + AVFrame * const p = data; + GetBitContext gb; + uint8_t *dst; + + if (avpkt->size <= 16) + return AVERROR_INVALIDDATA; + + if (AV_RL32(buf) != MKTAG('Y', 'L', 'C', '0') || + AV_RL32(buf + 4) != 0) + return AVERROR_INVALIDDATA; + + toffset = AV_RL32(buf + 8); + if (toffset < 16 || toffset >= avpkt->size) + return AVERROR_INVALIDDATA; + + boffset = AV_RL32(buf + 12); + if (toffset >= boffset || boffset >= avpkt->size) + return AVERROR_INVALIDDATA; + + if ((ret = ff_get_buffer(avctx, p, 0)) < 0) + return ret; + + av_fast_malloc(&s->table_bits, &s->table_bits_size, + boffset - toffset + AV_INPUT_BUFFER_PADDING_SIZE); + if (!s->table_bits) + return AVERROR(ENOMEM); + + memcpy(s->table_bits, avpkt->data + toffset, boffset - toffset); + memset(s->table_bits + boffset - toffset, 0, AV_INPUT_BUFFER_PADDING_SIZE); + s->bdsp.bswap_buf((uint32_t *) s->table_bits, + (uint32_t *) s->table_bits, + (boffset - toffset + 3) >> 2); + if ((ret = init_get_bits8(&gb, s->table_bits, boffset - toffset)) < 0) + return ret; + + for (x = 0; x < 1024; x++) { + unsigned len = get_unary(&gb, 1, 31); + uint32_t val = ((1U << len) - 1) + get_bits_long(&gb, len); + + s->table[x] = val; + } + + ret = build_vlc(avctx, &s->vlc[0], &s->table[0 ]); + if (ret < 0) + return ret; + ret = build_vlc(avctx, &s->vlc[1], &s->table[256]); + if (ret < 0) + return ret; + ret = build_vlc(avctx, &s->vlc[2], &s->table[512]); + if (ret < 0) + return ret; + ret = build_vlc(avctx, &s->vlc[3], &s->table[768]); + if (ret < 0) + return ret; + + av_fast_malloc(&s->bitstream_bits, &s->bitstream_bits_size, + avpkt->size - boffset + AV_INPUT_BUFFER_PADDING_SIZE); + if (!s->bitstream_bits) + return AVERROR(ENOMEM); + + memcpy(s->bitstream_bits, avpkt->data + boffset, avpkt->size - boffset); + memset(s->bitstream_bits + avpkt->size - boffset, 0, AV_INPUT_BUFFER_PADDING_SIZE); + s->bdsp.bswap_buf((uint32_t *) s->bitstream_bits, + (uint32_t *) s->bitstream_bits, + (avpkt->size - boffset) >> 2); + if ((ret = init_get_bits8(&gb, s->bitstream_bits, avpkt->size - boffset)) < 0) + return ret; + + dst = p->data[0]; + for (y = 0; y < avctx->height; y++) { + memset(dst, 0, avctx->width * 2); + dst += p->linesize[0]; + } + + dst = p->data[0]; + for (y = 0; y < avctx->height; y++) { + for (x = 0; x < avctx->width * 2 && y < avctx->height;) { + if (get_bits_left(&gb) <= 0) + return AVERROR_INVALIDDATA; + + if (get_bits1(&gb)) { + int val = get_vlc2(&gb, s->vlc[0].table, s->vlc[0].bits, 3); + if (val < 0) { + return AVERROR_INVALIDDATA; + } else if (val < 0xE1) { + dst[x ] = table_y1[val]; + dst[x + 1] = table_u[val]; + dst[x + 2] = table_y2[val]; + dst[x + 3] = table_v[val]; + x += 4; + } else { + int incr = (val - 0xDF) * 4; + if (x + incr >= avctx->width * 2) { + int iy = ((x + incr) / (avctx->width * 2)); + x = (x + incr) % (avctx->width * 2); + y += iy; + dst += iy * p->linesize[0]; + } else { + x += incr; + } + } + } else { + int y1, y2, u, v; + + y1 = get_vlc2(&gb, s->vlc[1].table, s->vlc[1].bits, 3); + u = get_vlc2(&gb, s->vlc[2].table, s->vlc[2].bits, 3); + y2 = get_vlc2(&gb, s->vlc[1].table, s->vlc[1].bits, 3); + v = get_vlc2(&gb, s->vlc[3].table, s->vlc[3].bits, 3); + if (y1 < 0 || y2 < 0 || u < 0 || v < 0) + return AVERROR_INVALIDDATA; + dst[x ] = y1; + dst[x + 1] = u; + dst[x + 2] = y1 + y2; + dst[x + 3] = v; + x += 4; + } + } + dst += p->linesize[0]; + } + + dst = p->data[0]; + for (x = 0; x < avctx->width * 2; x += 4) { + dst[x ] = dst[x ] + L[0]; + dst[x + 2] = L[0] = dst[x + 2] + L[0]; + L[1] = dst[x + 1] + L[1]; + dst[x + 1] = L[1]; + L[2] = dst[x + 3] + L[2]; + dst[x + 3] = L[2]; + } + dst += p->linesize[0]; + + for (y = 1; y < avctx->height; y++) { + x = 0; + dst[x ] = dst[x ] + L[0] + dst[x + 0 - p->linesize[0]] - TL[0]; + dst[x + 2] = L[0] = dst[x + 2] + L[0] + dst[x + 2 - p->linesize[0]] - TL[0]; + TL[0] = dst[x + 2 - p->linesize[0]]; + L[1] = dst[x + 1] + L[1] + dst[x + 1 - p->linesize[0]] - TL[1]; + dst[x + 1] = L[1]; + TL[1] = dst[x + 1 - p->linesize[0]]; + L[2] = dst[x + 3] + L[2] + dst[x + 3 - p->linesize[0]] - TL[2]; + dst[x + 3] = L[2]; + TL[2] = dst[x + 3 - p->linesize[0]]; + for (x = 4; x < avctx->width * 2; x += 4) { + dst[x ] = dst[x ] + L[0] + dst[x + 0 - p->linesize[0]] - TL[0]; + dst[x + 2] = L[0] = dst[x + 2] + L[0] + dst[x + 2 - p->linesize[0]] - TL[0]; + TL[0] = dst[x + 2 - p->linesize[0]]; + L[1] = dst[x + 1] + L[1] + dst[x + 1 - p->linesize[0]] - TL[1]; + dst[x + 1] = L[1]; + TL[1] = dst[x + 1 - p->linesize[0]]; + L[2] = dst[x + 3] + L[2] + dst[x + 3 - p->linesize[0]] - TL[2]; + dst[x + 3] = L[2]; + TL[2] = dst[x + 3 - p->linesize[0]]; + } + dst += p->linesize[0]; + } + + p->pict_type = AV_PICTURE_TYPE_I; + p->key_frame = 1; + *got_frame = 1; + + return avpkt->size; +} + +static av_cold int decode_end(AVCodecContext *avctx) +{ + YLCContext *s = avctx->priv_data; + + ff_free_vlc(&s->vlc[0]); + ff_free_vlc(&s->vlc[1]); + ff_free_vlc(&s->vlc[2]); + ff_free_vlc(&s->vlc[3]); + + return 0; +} + +AVCodec ff_ylc_decoder = { + .name = "ylc", + .long_name = NULL_IF_CONFIG_SMALL("YUY2 Lossless Codec"), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_YLC, + .priv_data_size = sizeof(YLCContext), + .init = decode_init, + .close = decode_end, + .decode = decode_frame, + .capabilities = AV_CODEC_CAP_DR1, +}; diff --git a/libavformat/riff.c b/libavformat/riff.c index f35fc7d686..913b42dae9 100644 --- a/libavformat/riff.c +++ b/libavformat/riff.c @@ -424,6 +424,7 @@ const AVCodecTag ff_codec_bmp_tags[] = { { AV_CODEC_ID_M101, MKTAG('M', '1', '0', '1') }, { AV_CODEC_ID_M101, MKTAG('M', '1', '0', '2') }, { AV_CODEC_ID_MAGICYUV, MKTAG('M', 'A', 'G', 'Y') }, + { AV_CODEC_ID_YLC, MKTAG('Y', 'L', 'C', '0') }, { AV_CODEC_ID_NONE, 0 } }; From 06a0e184359b75c3534bb88b08233efa53be8397 Mon Sep 17 00:00:00 2001 From: Hendrik Leppkes Date: Sun, 26 Jun 2016 15:34:40 +0200 Subject: [PATCH 36/37] hwcontext_dxva2: Use GetDesktopWindow instead of GetShellWindow Improves compatibility with some MinGW variants, see 771537edcf703434161c100e6898891546d1d4b3 --- libavutil/hwcontext_dxva2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavutil/hwcontext_dxva2.c b/libavutil/hwcontext_dxva2.c index d26f906717..e79254bb34 100644 --- a/libavutil/hwcontext_dxva2.c +++ b/libavutil/hwcontext_dxva2.c @@ -390,7 +390,7 @@ static int dxva2_device_create(AVHWDeviceContext *ctx, const char *device, d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.Flags = D3DPRESENTFLAG_VIDEO; - hr = IDirect3D9_CreateDevice(priv->d3d9, adapter, D3DDEVTYPE_HAL, GetShellWindow(), + hr = IDirect3D9_CreateDevice(priv->d3d9, adapter, D3DDEVTYPE_HAL, GetDesktopWindow(), D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE, &d3dpp, &priv->d3d9device); if (FAILED(hr)) { From e9394ca63dab3434bc8e869de019ecd86cb604ac Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 26 Jun 2016 17:34:37 +0200 Subject: [PATCH 37/37] avcodec/libopenjpegenc: Set numresolutions by default to a value that is not too large Fixes issues with libopenjpeg 2.1 Signed-off-by: Michael Niedermayer --- libavcodec/libopenjpegenc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libavcodec/libopenjpegenc.c b/libavcodec/libopenjpegenc.c index 56c8219633..14435515bc 100644 --- a/libavcodec/libopenjpegenc.c +++ b/libavcodec/libopenjpegenc.c @@ -352,6 +352,12 @@ static av_cold int libopenjpeg_encode_init(AVCodecContext *avctx) ctx->enc_params.cp_cinema = ctx->cinema_mode; #endif + if (!ctx->numresolution) { + ctx->numresolution = 6; + while (FFMIN(avctx->width, avctx->height) >> ctx->numresolution < 1) + ctx->numresolution --; + } + ctx->enc_params.mode = !!avctx->global_quality; ctx->enc_params.prog_order = ctx->prog_order; ctx->enc_params.numresolution = ctx->numresolution; @@ -815,7 +821,7 @@ static const AVOption options[] = { { "rpcl", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OPJ(RPCL) }, 0, 0, VE, "prog_order" }, { "pcrl", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OPJ(PCRL) }, 0, 0, VE, "prog_order" }, { "cprl", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = OPJ(CPRL) }, 0, 0, VE, "prog_order" }, - { "numresolution", NULL, OFFSET(numresolution), AV_OPT_TYPE_INT, { .i64 = 6 }, 1, INT_MAX, VE }, + { "numresolution", NULL, OFFSET(numresolution), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE }, { "numlayers", NULL, OFFSET(numlayers), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, 10, VE }, { "disto_alloc", NULL, OFFSET(disto_alloc), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, VE }, { "fixed_alloc", NULL, OFFSET(fixed_alloc), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },