[vlc-commits] [Git][videolan/vlc][master] 6 commits: codec: avcodec: map AYUV as RAWVIDEO with ffmpeg 6.0
Steve Lhomme (@robUx4)
gitlab at videolan.org
Thu Jun 6 09:34:10 UTC 2024
Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
955ef939 by François Cartegnie at 2024-06-06T08:46:28+00:00
codec: avcodec: map AYUV as RAWVIDEO with ffmpeg 6.0
- - - - -
cbbcb4eb by François Cartegnie at 2024-06-06T08:46:28+00:00
codec: avcodec: store using extended buf
- - - - -
a55ec32a by François Cartegnie at 2024-06-06T08:46:28+00:00
demux/mux: avformat: use ch_layout from ffmpeg 5.1
- - - - -
43009915 by François Cartegnie at 2024-06-06T08:46:28+00:00
codec: avcodec: non directly use reordered opaque
- - - - -
d29d0e3b by François Cartegnie at 2024-06-06T08:46:28+00:00
avcodec: vaapi: wipe sidedata on frame cloning
does not apply to next frame
would be better to have a clone API for buffers only
- - - - -
6b413351 by François Cartegnie at 2024-06-06T08:46:28+00:00
codec: avcodec: replace reordered_opaque with opaque_ref for ffmpeg 7.0
- - - - -
6 changed files:
- modules/codec/avcodec/audio.c
- modules/codec/avcodec/fourcc.c
- modules/codec/avcodec/vaapi.c
- modules/codec/avcodec/video.c
- modules/demux/avformat/demux.c
- modules/demux/avformat/mux.c
Changes:
=====================================
modules/codec/avcodec/audio.c
=====================================
@@ -138,7 +138,7 @@ static int OpenAudioCodec( decoder_t *p_dec )
}
ctx->sample_rate = p_dec->fmt_in->audio.i_rate;
-#if LIBAVCODEC_VERSION_CHECK(59, 24, 100)
+#if LIBAVUTIL_VERSION_CHECK(56, 31, 100)
av_channel_layout_default( &ctx->ch_layout, p_dec->fmt_in->audio.i_channels );
#else
ctx->channels = p_dec->fmt_in->audio.i_channels;
=====================================
modules/codec/avcodec/fourcc.c
=====================================
@@ -206,7 +206,11 @@ static const struct vlc_avcodec_fourcc video_codecs[] =
/* AV_CODEC_ID_V210X */
{ VLC_CODEC_TMV, AV_CODEC_ID_TMV },
{ VLC_CODEC_V210, AV_CODEC_ID_V210 },
+#if LIBAVCODEC_VERSION_CHECK( 59, 42, 102 )
+ { VLC_CODEC_VUYA, AV_CODEC_ID_RAWVIDEO },
+#else
{ VLC_CODEC_VUYA, AV_CODEC_ID_AYUV },
+#endif
/* AV_CODEC_ID_DPX */
{ VLC_CODEC_MAD, AV_CODEC_ID_MAD },
{ VLC_CODEC_FRWU, AV_CODEC_ID_FRWU },
=====================================
modules/codec/avcodec/vaapi.c
=====================================
@@ -129,6 +129,11 @@ static int Get(vlc_va_t *va, picture_t *pic, AVCodecContext *ctx, AVFrame *frame
vaapi_pic_ctx->ctx.surface = (uintptr_t) frame->data[3];
vaapi_pic_ctx->ctx.va_dpy = vaapi_vctx->va_dpy;
vaapi_pic_ctx->avframe = av_frame_clone(frame);
+#if LIBAVCODEC_VERSION_CHECK(61, 03, 100)
+ av_frame_side_data_free(&vaapi_pic_ctx->avframe->side_data, &vaapi_pic_ctx->avframe->nb_side_data);
+#endif
+ av_buffer_unref(&vaapi_pic_ctx->avframe->opaque_ref);
+ vaapi_pic_ctx->avframe->opaque = NULL;
vaapi_pic_ctx->cloned = false;
vlc_vaapi_PicSetContext(pic, &vaapi_pic_ctx->ctx);
=====================================
modules/codec/avcodec/video.c
=====================================
@@ -62,10 +62,14 @@
#include "../../packetizer/av1_obu.h"
#include "../../packetizer/av1.h"
#include "../cc.h"
-#define FRAME_INFO_DEPTH 64
+
+#define OPAQUE_REF_ONLY LIBAVCODEC_VERSION_CHECK( 59, 63, 100 )
struct frame_info_s
{
+#if OPAQUE_REF_ONLY
+ uint64_t i_sequence_number;
+#endif
bool b_eos;
bool b_display;
};
@@ -91,7 +95,12 @@ typedef struct
bool b_hardware_only;
enum AVDiscard i_skip_frame;
+#if OPAQUE_REF_ONLY
+ uint64_t i_next_sequence_number;
+#else
+# define FRAME_INFO_DEPTH 64
struct frame_info_s frame_info[FRAME_INFO_DEPTH];
+#endif
enum
{
@@ -151,6 +160,84 @@ static uint32_t ffmpeg_CodecTag( vlc_fourcc_t fcc )
* Local Functions
*****************************************************************************/
+static void FrameInfoInit( decoder_sys_t *p_sys )
+{
+#if OPAQUE_REF_ONLY
+ p_sys->i_next_sequence_number = 0;
+#else
+ AVCodecContext *p_context = p_sys->p_context;
+ p_context->reordered_opaque = 0;
+#endif
+}
+
+static struct frame_info_s * FrameInfoGet( decoder_sys_t *p_sys, AVFrame *frame )
+{
+#if OPAQUE_REF_ONLY
+ /* There's no pkt to frame opaque mapping guarantee */
+ return (struct frame_info_s *) frame->opaque_ref->data;
+#else
+ return &p_sys->frame_info[frame->reordered_opaque % FRAME_INFO_DEPTH];
+#endif
+}
+
+static struct frame_info_s * FrameInfoAdd( decoder_sys_t *p_sys, AVPacket *pkt )
+{
+#if OPAQUE_REF_ONLY
+ AVBufferRef *bufref = av_buffer_allocz(sizeof(struct frame_info_s));
+ if( !bufref )
+ return NULL;
+ pkt->opaque_ref = bufref;
+
+ struct frame_info_s *p_frame_info = (struct frame_info_s *) bufref->data;
+ p_frame_info->i_sequence_number = p_sys->i_next_sequence_number++;
+ return p_frame_info;
+#else
+ VLC_UNUSED(pkt);
+ AVCodecContext *p_context = p_sys->p_context;
+ return &p_sys->frame_info[p_context->reordered_opaque++ % FRAME_INFO_DEPTH];
+#endif
+}
+
+static bool FrameCanStoreInfo( const AVFrame *frame )
+{
+#if OPAQUE_REF_ONLY
+ return !!frame->opaque_ref;
+#else
+ return true;
+#endif
+}
+
+static void FrameSetPicture( AVFrame *frame, picture_t *pic )
+{
+ frame->opaque = pic;
+}
+
+static picture_t * FrameGetPicture( AVFrame *frame )
+{
+ return frame->opaque;
+}
+
+static int64_t NextPktSequenceNumber( decoder_sys_t *p_sys )
+{
+#if OPAQUE_REF_ONLY
+ return p_sys->i_next_sequence_number;
+#else
+ AVCodecContext *p_context = p_sys->p_context;
+ return p_context->reordered_opaque;
+#endif
+}
+
+static int64_t FrameSequenceNumber( const AVFrame *frame, const struct frame_info_s *info )
+{
+#if OPAQUE_REF_ONLY
+ VLC_UNUSED(frame);
+ return info->i_sequence_number;
+#else
+ VLC_UNUSED(info);
+ return frame->reordered_opaque;
+#endif
+}
+
static void lavc_Frame8PaletteCopy( video_palette_t *dst, const uint8_t *src )
{
// (A << 24) | (R << 16) | (G << 8) | B
@@ -481,6 +568,10 @@ static int InitVideoDecCommon( decoder_t *p_dec )
/* ***** Output always the frames ***** */
p_context->flags |= AV_CODEC_FLAG_OUTPUT_CORRUPT;
+#if OPAQUE_REF_ONLY
+ p_context->flags |= AV_CODEC_FLAG_COPY_OPAQUE;
+#endif
+
#if LIBAVCODEC_VERSION_CHECK( 61, 03, 100 )
if( p_dec->fmt_in->i_codec == VLC_CODEC_VVC )
p_context->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
@@ -534,7 +625,8 @@ static int InitVideoDecCommon( decoder_t *p_dec )
* PTS correctly */
p_context->get_buffer2 = lavc_GetFrame;
p_context->opaque = p_dec;
- p_context->reordered_opaque = 0;
+
+ FrameInfoInit( p_sys );
int max_thread_count;
int i_thread_count = p_sys->b_hardware_only ? 1 : var_InheritInteger( p_dec, "avcodec-threads" );
@@ -875,7 +967,7 @@ static block_t * filter_earlydropped_blocks( decoder_t *p_dec, block_t *block )
return block;
if( p_sys->i_last_output_frame >= 0 &&
- p_sys->p_context->reordered_opaque - p_sys->i_last_output_frame > 24 )
+ NextPktSequenceNumber( p_sys ) - p_sys->i_last_output_frame > 24 )
{
p_sys->framedrop = FRAMEDROP_AGGRESSIVE_RECOVER;
}
@@ -887,7 +979,7 @@ static block_t * filter_earlydropped_blocks( decoder_t *p_dec, block_t *block )
{
msg_Err( p_dec, "more than %"PRId64" frames of late video -> "
"dropping frame (computer too slow ?)",
- p_sys->p_context->reordered_opaque - p_sys->i_last_output_frame );
+ NextPktSequenceNumber( p_sys ) - p_sys->i_last_output_frame );
vlc_mutex_lock(&p_sys->lock);
date_Set( &p_sys->pts, VLC_TICK_INVALID ); /* To make sure we recover properly */
@@ -1334,6 +1426,17 @@ static int DecodeBlock( decoder_t *p_dec, block_t **pp_block )
p_block->i_dts = VLC_TICK_INVALID;
}
+ struct frame_info_s *p_frame_info = FrameInfoAdd( p_sys, pkt );
+ if( !p_frame_info )
+ {
+ av_packet_free( &pkt );
+ b_error = true;
+ break;
+ }
+ const bool b_eos = p_block && (p_block->i_flags & BLOCK_FLAG_END_OF_SEQUENCE);
+ p_frame_info->b_eos = b_eos;
+ p_frame_info->b_display = b_need_output_picture;
+
int ret = avcodec_send_packet(p_context, pkt);
if( ret != 0 && ret != AVERROR(EAGAIN) )
{
@@ -1346,15 +1449,10 @@ static int DecodeBlock( decoder_t *p_dec, block_t **pp_block )
break;
}
- struct frame_info_s *p_frame_info = &p_sys->frame_info[p_context->reordered_opaque % FRAME_INFO_DEPTH];
- p_frame_info->b_eos = p_block && (p_block->i_flags & BLOCK_FLAG_END_OF_SEQUENCE);
- p_frame_info->b_display = b_need_output_picture;
-
- p_context->reordered_opaque++;
i_used = ret != AVERROR(EAGAIN) ? pkt->size : 0;
av_packet_free( &pkt );
- if( p_frame_info->b_eos && !b_drained )
+ if( b_eos && !b_drained )
{
avcodec_send_packet( p_context, NULL );
b_drained = true;
@@ -1397,8 +1495,8 @@ static int DecodeBlock( decoder_t *p_dec, block_t **pp_block )
continue;
}
- struct frame_info_s *p_frame_info = &p_sys->frame_info[frame->reordered_opaque % FRAME_INFO_DEPTH];
- if( p_frame_info->b_eos )
+ struct frame_info_s *p_frame_info = FrameInfoGet( p_sys, frame );
+ if( p_frame_info && p_frame_info->b_eos )
p_sys->b_first_frame = true;
vlc_mutex_lock(&p_sys->lock);
@@ -1426,12 +1524,13 @@ static int DecodeBlock( decoder_t *p_dec, block_t **pp_block )
if( b_first_output_sequence )
{
- update_late_frame_count( p_dec, p_block, vlc_tick_now(), i_pts,
- i_next_pts, frame->reordered_opaque);
+ if( p_frame_info )
+ update_late_frame_count( p_dec, p_block, vlc_tick_now(), i_pts,
+ i_next_pts, FrameSequenceNumber( frame, p_frame_info ) );
b_first_output_sequence = false;
}
- if( !p_frame_info->b_display ||
+ if( (p_frame_info && !p_frame_info->b_display) ||
( !p_sys->p_va && !frame->linesize[0] ) ||
( p_dec->b_frame_drop_allowed && (frame->flags & AV_FRAME_FLAG_CORRUPT) &&
!p_sys->b_show_corrupted ) )
@@ -1472,7 +1571,7 @@ static int DecodeBlock( decoder_t *p_dec, block_t **pp_block )
}
}
- picture_t *p_pic = frame->opaque;
+ picture_t *p_pic = FrameGetPicture( frame );
if( p_pic == NULL )
{ /* When direct rendering is not used, get_format() and get_buffer()
* might not be called. The output video format must be set here
@@ -1536,6 +1635,7 @@ static int DecodeBlock( decoder_t *p_dec, block_t **pp_block )
p_pic->i_nb_fields = 2 + frame->repeat_pict;
p_pic->b_progressive = !frame->interlaced_frame;
p_pic->b_top_field_first = frame->top_field_first;
+ p_pic->b_still = p_frame_info && p_frame_info->b_eos;
if (DecodeSidedata(p_dec, frame, p_pic))
i_pts = VLC_TICK_INVALID;
@@ -1545,8 +1645,6 @@ static int DecodeBlock( decoder_t *p_dec, block_t **pp_block )
/* Send decoded frame to vout */
if (i_pts != VLC_TICK_INVALID)
{
- if(p_frame_info->b_eos)
- p_pic->b_still = true;
p_sys->b_first_frame = false;
vlc_mutex_unlock(&p_sys->lock);
decoder_QueueVideo( p_dec, p_pic );
@@ -1700,6 +1798,9 @@ static int lavc_va_GetFrame(struct AVCodecContext *ctx, AVFrame *frame)
decoder_sys_t *p_sys = dec->p_sys;
vlc_va_t *va = p_sys->p_va;
+ if(!FrameCanStoreInfo(frame))
+ return -1;
+
picture_t *pic;
pic = decoder_NewPicture(dec);
if (pic == NULL)
@@ -1724,9 +1825,20 @@ static int lavc_va_GetFrame(struct AVCodecContext *ctx, AVFrame *frame)
if (frame->buf[0] == NULL)
frame->buf[0] = buf;
else
- frame->opaque_ref = buf;
+ {
+ AVBufferRef **extended_buf = av_realloc_array(frame->extended_buf,
+ sizeof(*extended_buf),
+ frame->nb_extended_buf + 1);
+ if(!extended_buf)
+ {
+ av_buffer_unref(&buf);
+ return -1;
+ }
+ frame->extended_buf = extended_buf;
+ frame->extended_buf[frame->nb_extended_buf++] = buf;
+ }
- frame->opaque = pic;
+ FrameSetPicture( frame, pic );
return 0;
}
@@ -1794,7 +1906,7 @@ static int lavc_dr_GetFrame(struct AVCodecContext *ctx, AVFrame *frame)
picture_Hold(pic);
}
- frame->opaque = pic;
+ FrameSetPicture( frame, pic );
/* The loop above held one reference to the picture for each plane. */
assert(pic->i_planes > 0);
picture_Release(pic);
@@ -1821,7 +1933,7 @@ static int lavc_GetFrame(struct AVCodecContext *ctx, AVFrame *frame, int flags)
frame->linesize[i] = 0;
frame->buf[i] = NULL;
}
- frame->opaque = NULL;
+ FrameSetPicture( frame, NULL );
vlc_mutex_lock(&sys->lock);
if (sys->p_va == NULL)
=====================================
modules/demux/avformat/demux.c
=====================================
@@ -470,7 +470,11 @@ int avformat_OpenDemux( vlc_object_t *p_this )
es_format_Init( &es_fmt, AUDIO_ES, fcc );
es_fmt.i_original_fourcc = CodecTagToFourcc( cp->codec_tag );
es_fmt.i_bitrate = cp->bit_rate;
+#if LIBAVUTIL_VERSION_CHECK(56, 31, 100)
+ es_fmt.audio.i_channels = cp->ch_layout.nb_channels;
+#else
es_fmt.audio.i_channels = cp->channels;
+#endif
es_fmt.audio.i_rate = cp->sample_rate;
es_fmt.audio.i_bitspersample = cp->bits_per_coded_sample;
es_fmt.audio.i_blockalign = cp->block_align;
=====================================
modules/demux/avformat/mux.c
=====================================
@@ -271,7 +271,11 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
{
case AUDIO_ES:
codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
+#if LIBAVUTIL_VERSION_CHECK(56, 31, 100)
+ av_channel_layout_default( &codecpar->ch_layout, fmt->audio.i_channels );
+#else
codecpar->channels = fmt->audio.i_channels;
+#endif
codecpar->sample_rate = fmt->audio.i_rate;
stream->time_base = (AVRational){1, codecpar->sample_rate};
if (fmt->i_bitrate == 0) {
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/c7c55ad4923bfe64bd149fa0c9230a936684e6c3...6b413351fbdcb6e7bbb25dc693d4318b0b894c30
--
This project does not include diff previews in email notifications.
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/c7c55ad4923bfe64bd149fa0c9230a936684e6c3...6b413351fbdcb6e7bbb25dc693d4318b0b894c30
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list