1 /* $Id: decavcodec.c,v 1.6 2005/03/06 04:08:54 titer Exp $
3 This file is part of the HandBrake source code.
4 Homepage: <http://handbrake.fr/>.
5 It may be used under the terms of the GNU General Public License. */
7 /* This module is Handbrake's interface to the ffmpeg decoder library
8 (libavcodec & small parts of libavformat). It contains four Handbrake
11 decavcodec connects HB to an ffmpeg audio decoder
12 decavcodecv connects HB to an ffmpeg video decoder
14 (Two different routines are needed because the ffmpeg library
15 has different decoder calling conventions for audio & video.
16 The audio decoder should have had its name changed to "decavcodeca"
17 but I got lazy.) These work objects are self-contained & follow all
18 of HB's conventions for a decoder module. They can be used like
19 any other HB decoder (deca52, decmpeg2, etc.).
21 decavcodecai "internal" (incestuous?) version of decavcodec
22 decavcodecvi "internal" (incestuous?) version of decavcodecv
24 These routine are functionally equivalent to the routines above but
25 can only be used by the ffmpeg-based stream reader in libhb/stream.c.
26 The reason they exist is because the ffmpeg library leaves some of
27 the information needed by the decoder in the AVStream (the data
28 structure used by the stream reader) and we need to retrieve it
29 to successfully decode frames. But in HB the reader and decoder
30 modules are in completely separate threads and nothing goes between
31 them but hb_buffers containing frames to be decoded. I.e., there's
32 no easy way for the ffmpeg stream reader to pass a pointer to its
33 AVStream over to the ffmpeg video or audio decoder. So the *i work
34 objects use a private back door to the stream reader to get access
35 to the AVStream (routines hb_ffmpeg_avstream and hb_ffmpeg_context)
36 and the codec_param passed to these work objects is the key to this
37 back door (it's basically an index that allows the correct AVStream
40 The normal & *i objects share a lot of code (the basic frame decoding
41 and bitstream info code is factored out into subroutines that can be
42 called by either) but the top level routines of the *i objects
43 (decavcodecviWork, decavcodecviInfo, etc.) are different because:
44 1) they *have* to use the AVCodecContext that's contained in the
45 reader's AVStream rather than just allocating & using their own,
46 2) the Info routines have access to stuff kept in the AVStream in addition
47 to stuff kept in the AVCodecContext. This shouldn't be necessary but
48 crucial information like video frame rate that should be in the
49 AVCodecContext is either missing or wrong in the version of ffmpeg
50 we're currently using.
52 A consequence of the above is that the non-i work objects *can't* use
53 information from the AVStream because there isn't one - they get their
54 data from either the dvd reader or the mpeg reader, not the ffmpeg stream
55 reader. That means that they have to make up for deficiencies in the
56 AVCodecContext info by using stuff kept in the HB "title" struct. It
57 also means that ffmpeg codecs that randomly scatter state needed by
58 the decoder across both the AVCodecContext & the AVStream (e.g., the
59 VC1 decoder) can't easily be used by the HB mpeg stream reader.
64 #include "libavcodec/avcodec.h"
65 #include "libavformat/avformat.h"
67 static int decavcodecInit( hb_work_object_t *, hb_job_t * );
68 static int decavcodecWork( hb_work_object_t *, hb_buffer_t **, hb_buffer_t ** );
69 static void decavcodecClose( hb_work_object_t * );
70 static int decavcodecInfo( hb_work_object_t *, hb_work_info_t * );
71 static int decavcodecBSInfo( hb_work_object_t *, const hb_buffer_t *, hb_work_info_t * );
73 hb_work_object_t hb_decavcodec =
76 "MPGA decoder (libavcodec)",
84 struct hb_work_private_s
87 AVCodecContext *context;
88 AVCodecParserContext *parser;
90 double pts_next; // next pts we expect to generate
91 int64_t pts; // (video) pts passing from parser to decoder
92 int64_t chap_time; // time of next chap mark (if new_chap != 0)
94 int ignore_pts; // workaround M$ bugs
97 double duration; // frame duration (for video)
102 /***********************************************************************
103 * hb_work_decavcodec_init
104 ***********************************************************************
106 **********************************************************************/
107 static int decavcodecInit( hb_work_object_t * w, hb_job_t * job )
111 hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
112 w->private_data = pv;
116 int codec_id = w->codec_param;
119 codec_id = CODEC_ID_MP2;
120 codec = avcodec_find_decoder( codec_id );
121 pv->parser = av_parser_init( codec_id );
123 pv->context = avcodec_alloc_context();
124 avcodec_open( pv->context, codec );
129 /***********************************************************************
131 ***********************************************************************
133 **********************************************************************/
134 static void decavcodecClose( hb_work_object_t * w )
136 hb_work_private_t * pv = w->private_data;
139 av_parser_close(pv->parser);
141 if ( pv->context && pv->context->codec )
143 avcodec_close( pv->context );
147 hb_list_close( &pv->list );
151 /***********************************************************************
153 ***********************************************************************
155 **********************************************************************/
156 static int decavcodecWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
157 hb_buffer_t ** buf_out )
159 hb_work_private_t * pv = w->private_data;
160 hb_buffer_t * in = *buf_in, * buf, * last = NULL;
161 int pos, len, out_size, i, uncompressed_len;
162 short buffer[AVCODEC_MAX_AUDIO_FRAME_SIZE];
164 unsigned char *parser_output_buffer;
165 int parser_output_buffer_len;
167 if ( (*buf_in)->size <= 0 )
169 /* EOF on input stream - send it downstream & say that we're done */
177 cur = ( in->start < 0 )? pv->pts_next : in->start;
180 while( pos < in->size )
182 len = av_parser_parse( pv->parser, pv->context,
183 &parser_output_buffer, &parser_output_buffer_len,
184 in->data + pos, in->size - pos, cur, cur );
186 uncompressed_len = 0;
187 if (parser_output_buffer_len)
189 out_size = sizeof(buffer);
190 uncompressed_len = avcodec_decode_audio2( pv->context, buffer,
192 parser_output_buffer,
193 parser_output_buffer_len );
200 buf = hb_buffer_init( 2 * out_size );
202 int sample_size_in_bytes = 2; // Default to 2 bytes
203 switch (pv->context->sample_fmt)
206 sample_size_in_bytes = 2;
208 /* We should handle other formats here - but that needs additional format conversion work below */
209 /* For now we'll just report the error and try to carry on */
211 hb_log("decavcodecWork - Unknown Sample Format from avcodec_decode_audio (%d) !", pv->context->sample_fmt);
216 buf->stop = cur + 90000 * ( out_size / (sample_size_in_bytes * pv->context->channels) ) /
217 pv->context->sample_rate;
221 fl32 = (float *) buf->data;
222 for( i = 0; i < out_size / 2; i++ )
229 last = last->next = buf;
233 *buf_out = last = buf;
245 static int decavcodecInfo( hb_work_object_t *w, hb_work_info_t *info )
247 hb_work_private_t *pv = w->private_data;
249 memset( info, 0, sizeof(*info) );
251 if ( pv && pv->context )
253 AVCodecContext *context = pv->context;
254 info->bitrate = context->bit_rate;
255 info->rate = context->time_base.num;
256 info->rate_base = context->time_base.den;
257 info->profile = context->profile;
258 info->level = context->level;
264 static int decavcodecBSInfo( hb_work_object_t *w, const hb_buffer_t *buf,
265 hb_work_info_t *info )
267 hb_work_private_t *pv = w->private_data;
269 memset( info, 0, sizeof(*info) );
271 if ( pv && pv->context )
273 return decavcodecInfo( w, info );
276 // We should parse the bitstream to find its parameters but for right
277 // now we just return dummy values if there's a codec that will handle it.
278 AVCodec *codec = avcodec_find_decoder( w->codec_param? w->codec_param :
282 static char codec_name[64];
284 info->name = strncpy( codec_name, codec->name, sizeof(codec_name)-1 );
285 info->bitrate = 384000;
288 info->channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
294 /* -------------------------------------------------------------
295 * General purpose video decoder using libavcodec
298 static uint8_t *copy_plane( uint8_t *dst, uint8_t* src, int dstride, int sstride,
301 if ( dstride == sstride )
303 memcpy( dst, src, dstride * h );
304 return dst + dstride * h;
306 int lbytes = dstride <= sstride? dstride : sstride;
309 memcpy( dst, src, lbytes );
316 /* Note: assumes frame format is PIX_FMT_YUV420P */
317 static hb_buffer_t *copy_frame( AVCodecContext *context, AVFrame *frame )
319 int w = context->width, h = context->height;
320 hb_buffer_t *buf = hb_buffer_init( w * h * 3 / 2 );
321 uint8_t *dst = buf->data;
323 dst = copy_plane( dst, frame->data[0], w, frame->linesize[0], h );
325 dst = copy_plane( dst, frame->data[1], w, frame->linesize[1], h );
326 dst = copy_plane( dst, frame->data[2], w, frame->linesize[2], h );
331 static int get_frame_buf( AVCodecContext *context, AVFrame *frame )
333 hb_work_private_t *pv = context->opaque;
334 frame->pts = pv->pts;
337 return avcodec_default_get_buffer( context, frame );
340 static void log_chapter( hb_work_private_t *pv, int chap_num, int64_t pts )
342 hb_chapter_t *c = hb_list_item( pv->job->title->list_chapter, chap_num - 1 );
343 hb_log( "%s: \"%s\" (%d) at frame %u time %lld", pv->context->codec->name,
344 c->title, chap_num, pv->nframes, pts );
347 static int decodeFrame( hb_work_private_t *pv, uint8_t *data, int size )
352 avcodec_decode_video( pv->context, &frame, &got_picture, data, size );
355 // ffmpeg makes it hard to attach a pts to a frame. if the MPEG ES
356 // packet had a pts we handed it to av_parser_parse (if the packet had
357 // no pts we set it to -1 but before the parse we can't distinguish between
358 // the start of a video frame with no pts & an intermediate packet of
359 // some frame which never has a pts). we hope that when parse returns
360 // the frame to us the pts we originally handed it will be in parser->pts.
361 // we put this pts into pv->pts so that when a avcodec_decode_video
362 // finally gets around to allocating an AVFrame to hold the decoded
363 // frame we can stuff that pts into the frame. if all of these relays
364 // worked at this point frame.pts should hold the frame's pts from the
365 // original data stream or -1 if it didn't have one. in the latter case
366 // we generate the next pts in sequence for it.
367 double pts = frame.pts;
372 if ( pv->duration == 0 )
374 pv->duration = 90000. * pv->context->time_base.num /
375 pv->context->time_base.den;
377 double frame_dur = pv->duration;
378 frame_dur += frame.repeat_pict * frame_dur * 0.5;
379 pv->pts_next = pts + frame_dur;
381 hb_buffer_t *buf = copy_frame( pv->context, &frame );
384 if ( pv->new_chap && buf->start >= pv->chap_time )
386 buf->new_chap = pv->new_chap;
391 log_chapter( pv, buf->new_chap, buf->start );
394 else if ( pv->job && pv->nframes == 0 )
396 log_chapter( pv, pv->job->chapter_start, buf->start );
398 hb_list_add( pv->list, buf );
404 static void decodeVideo( hb_work_private_t *pv, uint8_t *data, int size,
405 int64_t pts, int64_t dts )
408 * The following loop is a do..while because we need to handle both
409 * data & the flush at the end (signaled by size=0). At the end there's
410 * generally a frame in the parser & one or more frames in the decoder
411 * (depending on the bframes setting).
417 int len = av_parser_parse( pv->parser, pv->context, &pout, &pout_len,
418 data + pos, size - pos, pts, dts );
423 pv->pts = pv->parser->pts;
424 decodeFrame( pv, pout, pout_len );
426 } while ( pos < size );
428 /* the stuff above flushed the parser, now flush the decoder */
429 while ( size == 0 && decodeFrame( pv, NULL, 0 ) )
434 static hb_buffer_t *link_buf_list( hb_work_private_t *pv )
436 hb_buffer_t *head = hb_list_item( pv->list, 0 );
440 hb_list_rem( pv->list, head );
442 hb_buffer_t *last = head, *buf;
444 while ( ( buf = hb_list_item( pv->list, 0 ) ) != NULL )
446 hb_list_rem( pv->list, buf );
455 static int decavcodecvInit( hb_work_object_t * w, hb_job_t * job )
458 hb_work_private_t *pv = calloc( 1, sizeof( hb_work_private_t ) );
459 w->private_data = pv;
461 pv->list = hb_list_init();
463 int codec_id = w->codec_param;
464 pv->parser = av_parser_init( codec_id );
465 pv->context = avcodec_alloc_context2( CODEC_TYPE_VIDEO );
467 /* we have to wrap ffmpeg's get_buffer to be able to set the pts (?!) */
468 pv->context->opaque = pv;
469 pv->context->get_buffer = get_frame_buf;
471 AVCodec *codec = avcodec_find_decoder( codec_id );
473 // we can't call the avstream funcs but the read_header func in the
474 // AVInputFormat may set up some state in the AVContext. In particular
475 // vc1t_read_header allocates 'extradata' to deal with header issues
476 // related to Microsoft's bizarre engineering notions. We alloc a chunk
477 // of space to make vc1 work then associate the codec with the context.
478 pv->context->extradata_size = 32;
479 pv->context->extradata = av_malloc(pv->context->extradata_size);
480 avcodec_open( pv->context, codec );
485 static int decavcodecvWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
486 hb_buffer_t ** buf_out )
488 hb_work_private_t *pv = w->private_data;
489 hb_buffer_t *in = *buf_in;
495 /* if we got an empty buffer signaling end-of-stream send it downstream */
498 decodeVideo( pv, in->data, in->size, pts, dts );
499 hb_list_add( pv->list, in );
500 *buf_out = link_buf_list( pv );
501 hb_log( "%s done: %d frames", pv->context->codec->name, pv->nframes );
508 dts = in->renderOffset;
512 pv->new_chap = in->new_chap;
513 pv->chap_time = pts >= 0? pts : pv->pts_next;
515 decodeVideo( pv, in->data, in->size, pts, dts );
516 hb_buffer_close( &in );
517 *buf_out = link_buf_list( pv );
521 static int decavcodecvInfo( hb_work_object_t *w, hb_work_info_t *info )
523 hb_work_private_t *pv = w->private_data;
525 memset( info, 0, sizeof(*info) );
527 if ( pv && pv->context )
529 AVCodecContext *context = pv->context;
530 info->bitrate = context->bit_rate;
531 info->width = context->width;
532 info->height = context->height;
534 /* ffmpeg gives the frame rate in frames per second while HB wants
535 * it in units of the 27MHz MPEG clock. */
536 info->rate = 27000000;
537 info->rate_base = (int64_t)context->time_base.num * 27000000LL /
538 context->time_base.den;
540 /* Sometimes there's no pixel aspect set in the source. In that case,
541 assume a 1:1 PAR. Otherwise, preserve the source PAR. */
542 info->pixel_aspect_width = context->sample_aspect_ratio.num ?
543 context->sample_aspect_ratio.num : 1;
544 info->pixel_aspect_height = context->sample_aspect_ratio.den ?
545 context->sample_aspect_ratio.den : 1;
547 /* ffmpeg returns the Pixel Aspect Ratio (PAR). Handbrake wants the
548 * Display Aspect Ratio so we convert by scaling by the Storage
549 * Aspect Ratio (w/h). We do the calc in floating point to get the
551 info->aspect = (double)info->pixel_aspect_width *
552 (double)context->width /
553 (double)info->pixel_aspect_height /
554 (double)context->height;
556 info->profile = context->profile;
557 info->level = context->level;
558 info->name = context->codec->name;
564 static int decavcodecvBSInfo( hb_work_object_t *w, const hb_buffer_t *buf,
565 hb_work_info_t *info )
570 hb_work_object_t hb_decavcodecv =
573 "Video decoder (libavcodec)",
582 // This is a special decoder for ffmpeg streams. The ffmpeg stream reader
583 // includes a parser and passes information from the parser to the decoder
584 // via a codec context kept in the AVStream of the reader's AVFormatContext.
585 // We *have* to use that codec context to decode the stream or we'll get
586 // garbage. ffmpeg_title_scan put a cookie that can be used to get to that
587 // codec context in our codec_param.
589 // this routine gets the appropriate context pointer from the ffmpeg
590 // stream reader. it can't be called until we get the first buffer because
591 // we can't guarantee that reader will be called before the our init
592 // routine and if our init is called first we'll get a pointer to the
593 // old scan stream (which has already been closed).
594 static void init_ffmpeg_context( hb_work_object_t *w )
596 hb_work_private_t *pv = w->private_data;
597 pv->context = hb_ffmpeg_context( w->codec_param );
599 // during scan the decoder gets closed & reopened which will
600 // close the codec so reopen it if it's not there
601 if ( ! pv->context->codec )
603 AVCodec *codec = avcodec_find_decoder( pv->context->codec_id );
604 avcodec_open( pv->context, codec );
606 // set up our best guess at the frame duration.
607 // the frame rate in the codec is usually bogus but it's sometimes
609 AVStream *st = hb_ffmpeg_avstream( w->codec_param );
611 // XXX because the time bases are so screwed up, we only take values
612 // in the range 8fps - 64fps.
613 if ( st->time_base.num * 64 > st->time_base.den &&
614 st->time_base.den > st->time_base.num * 8 )
618 else if ( st->codec->time_base.num * 64 > st->codec->time_base.den &&
619 st->codec->time_base.den > st->codec->time_base.num * 8 )
621 tb = st->codec->time_base;
623 else if ( st->r_frame_rate.den * 64 > st->r_frame_rate.num &&
624 st->r_frame_rate.num > st->r_frame_rate.den * 8 )
626 tb.num = st->r_frame_rate.den;
627 tb.den = st->r_frame_rate.num;
631 tb.num = 1001; /*XXX*/
632 tb.den = 30000; /*XXX*/
634 pv->duration = 90000. * tb.num / tb.den;
636 // we have to wrap ffmpeg's get_buffer to be able to set the pts (?!)
637 pv->context->opaque = pv;
638 pv->context->get_buffer = get_frame_buf;
641 static void prepare_ffmpeg_buffer( hb_buffer_t * in )
643 // ffmpeg requires an extra 8 bytes of zero at the end of the buffer and
644 // will seg fault in odd, data dependent ways if it's not there. (my guess
645 // is this is a case of a local performance optimization creating a global
646 // performance degradation since all the time wasted by extraneous data
647 // copies & memory zeroing has to be huge compared to the minor reduction
648 // in inner-loop instructions this affords - modern cpus bottleneck on
649 // memory bandwidth not instruction bandwidth).
650 if ( in->size + FF_INPUT_BUFFER_PADDING_SIZE > in->alloc )
652 // have to realloc to add the padding
653 hb_buffer_realloc( in, in->size + FF_INPUT_BUFFER_PADDING_SIZE );
655 memset( in->data + in->size, 0, FF_INPUT_BUFFER_PADDING_SIZE );
658 static int decavcodecviInit( hb_work_object_t * w, hb_job_t * job )
661 hb_work_private_t *pv = calloc( 1, sizeof( hb_work_private_t ) );
662 w->private_data = pv;
664 pv->list = hb_list_init();
669 static int decavcodecviWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
670 hb_buffer_t ** buf_out )
672 hb_work_private_t *pv = w->private_data;
675 init_ffmpeg_context( w );
677 switch ( pv->context->codec_id )
679 // These are the only formats whose timestamps we'll believe.
680 // All others are treated as CFR (i.e., we take the first timestamp
681 // then generate all the others from the frame rate). The reason for
682 // this is that the M$ encoders are so frigging buggy with garbage
683 // like packed b-frames (vfw divx mpeg4) that believing their timestamps
684 // results in discarding more than half the video frames because they'll
685 // be out of sequence (and attempting to reseqence them doesn't work
686 // because it's the timestamps that are wrong, not the decoded frame
687 // order). All hail Redmond, ancestral home of the rich & stupid.
688 case CODEC_ID_MPEG2VIDEO:
689 case CODEC_ID_RAWVIDEO:
699 hb_buffer_t *in = *buf_in;
704 /* if we got an empty buffer signaling end-of-stream send it downstream */
707 /* flush any frames left in the decoder */
708 while ( decodeFrame( pv, NULL, 0 ) )
711 hb_list_add( pv->list, in );
712 *buf_out = link_buf_list( pv );
713 hb_log( "%s done: %d frames %d drops", pv->context->codec->name,
714 pv->nframes, pv->ndrops );
720 // use the first timestamp as our 'next expected' pts
721 if ( pv->pts_next <= 0 )
723 pv->pts_next = in->start;
726 if ( ! pv->ignore_pts )
731 hb_log( "overwriting pts %lld with %lld (diff %d)",
732 pv->pts, pts, pts - pv->pts );
734 if ( pv->pts_next - pts >= pv->duration )
736 // this frame starts more than a frame time before where
737 // the nominal frame rate says it should - drop it.
738 // log the first 10 drops so we'll know what's going on.
739 if ( pv->ndrops++ < 10 )
741 hb_log( "time reversal next %.0f pts %lld (diff %g)",
742 pv->pts_next, pts, pv->pts_next - pts );
744 hb_buffer_close( &in );
753 pv->new_chap = in->new_chap;
754 pv->chap_time = pts >= 0? pts : pv->pts_next;
756 prepare_ffmpeg_buffer( in );
757 decodeFrame( pv, in->data, in->size );
758 hb_buffer_close( &in );
759 *buf_out = link_buf_list( pv );
763 static int decavcodecviInfo( hb_work_object_t *w, hb_work_info_t *info )
765 if ( decavcodecvInfo( w, info ) )
767 // There are at least three different video frame rates in ffmpeg:
768 // - time_base in the AVStream
769 // - time_base in the AVCodecContext
770 // - r_frame_rate in the AVStream
771 // There's no guidence on which if any of these to believe but the
772 // routine compute_frame_duration tries the stream first then the codec.
773 // In general the codec time base seems bogus & the stream time base is
774 // ok except for wmv's where the stream time base is also bogus but
775 // r_frame_rate is sometimes ok & sometimes a random number.
776 AVStream *st = hb_ffmpeg_avstream( w->codec_param );
778 // XXX because the time bases are so screwed up, we only take values
779 // in the range 8fps - 64fps.
780 if ( st->time_base.num * 64 > st->time_base.den &&
781 st->time_base.den > st->time_base.num * 8 )
785 else if ( st->codec->time_base.num * 64 > st->codec->time_base.den &&
786 st->codec->time_base.den > st->codec->time_base.num * 8 )
788 tb = st->codec->time_base;
790 else if ( st->r_frame_rate.den * 64 > st->r_frame_rate.num &&
791 st->r_frame_rate.num > st->r_frame_rate.den * 8 )
793 tb.num = st->r_frame_rate.den;
794 tb.den = st->r_frame_rate.num;
798 tb.num = 1001; /*XXX*/
799 tb.den = 30000; /*XXX*/
802 // ffmpeg gives the frame rate in frames per second while HB wants
803 // it in units of the 27MHz MPEG clock. */
804 info->rate = 27000000;
805 info->rate_base = (int64_t)tb.num * 27000000LL / tb.den;
811 static void decodeAudio( hb_work_private_t *pv, uint8_t *data, int size )
813 AVCodecContext *context = pv->context;
818 int16_t buffer[AVCODEC_MAX_AUDIO_FRAME_SIZE];
819 int out_size = sizeof(buffer);
820 int len = avcodec_decode_audio2( context, buffer, &out_size,
821 data + pos, size - pos );
829 hb_buffer_t *buf = hb_buffer_init( 2 * out_size );
831 double pts = pv->pts_next;
834 pts += out_size * pv->duration;
838 float *fl32 = (float *)buf->data;
840 for( i = 0; i < out_size; ++i )
844 hb_list_add( pv->list, buf );
849 static int decavcodecaiWork( hb_work_object_t *w, hb_buffer_t **buf_in,
850 hb_buffer_t **buf_out )
852 if ( (*buf_in)->size <= 0 )
854 /* EOF on input stream - send it downstream & say that we're done */
860 hb_work_private_t *pv = w->private_data;
863 init_ffmpeg_context( w );
864 pv->duration = 90000. /
865 (double)( pv->context->sample_rate * pv->context->channels );
867 hb_buffer_t *in = *buf_in;
869 if ( in->start >= 0 &&
870 ( pv->pts_next < 0 || ( in->start - pv->pts_next ) > 90*100 ) )
872 pv->pts_next = in->start;
874 prepare_ffmpeg_buffer( in );
875 decodeAudio( pv, in->data, in->size );
876 *buf_out = link_buf_list( pv );
881 hb_work_object_t hb_decavcodecvi =
884 "Video decoder (ffmpeg streams)",
892 hb_work_object_t hb_decavcodecai =
895 "Audio decoder (ffmpeg streams)",