[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