OSDN Git Service

bump ffmpeg to rev 22950
[handbrake-jp/handbrake-jp-git.git] / libhb / decavcodec.c
1 /* $Id: decavcodec.c,v 1.6 2005/03/06 04:08:54 titer Exp $
2
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. */
6
7 /* This module is Handbrake's interface to the ffmpeg decoder library
8    (libavcodec & small parts of libavformat). It contains four Handbrake
9    "work objects":
10
11     decavcodec  connects HB to an ffmpeg audio decoder
12     decavcodecv connects HB to an ffmpeg video decoder
13
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.).
20
21     decavcodecai "internal" (incestuous?) version of decavcodec
22     decavcodecvi "internal" (incestuous?) version of decavcodecv
23
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
38         to be retrieved).
39
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.
51
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.
60  */
61
62 #include "hb.h"
63 #include "hbffmpeg.h"
64 #include "downmix.h"
65 #include "libavcodec/audioconvert.h"
66
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 * );
72
73 hb_work_object_t hb_decavcodec =
74 {
75     WORK_DECAVCODEC,
76     "MPGA decoder (libavcodec)",
77     decavcodecInit,
78     decavcodecWork,
79     decavcodecClose,
80     decavcodecInfo,
81     decavcodecBSInfo
82 };
83
84 #define HEAP_SIZE 8
85 typedef struct {
86     // there are nheap items on the heap indexed 1..nheap (i.e., top of
87     // heap is 1). The 0th slot is unused - a marker is put there to check
88     // for overwrite errs.
89     int64_t h[HEAP_SIZE+1];
90     int     nheap;
91 } pts_heap_t;
92
93 struct hb_work_private_s
94 {
95     hb_job_t        *job;
96     AVCodecContext  *context;
97     AVCodecParserContext *parser;
98     hb_list_t       *list;
99     double          duration;   // frame duration (for video)
100     double          pts_next;   // next pts we expect to generate
101     int64_t         pts;        // (video) pts passing from parser to decoder
102     int64_t         chap_time;  // time of next chap mark (if new_chap != 0)
103     int             new_chap;   // output chapter mark pending
104     uint32_t        nframes;
105     uint32_t        ndrops;
106     uint32_t        decode_errors;
107     int             brokenByMicrosoft; // video stream may contain packed b-frames
108     hb_buffer_t*    delayq[HEAP_SIZE];
109     pts_heap_t      pts_heap;
110     void*           buffer;
111     struct SwsContext *sws_context; // if we have to rescale or convert color space
112     hb_downmix_t    *downmix;
113     hb_sample_t     *downmix_buffer;
114 };
115
116 static void decodeAudio( hb_audio_t * audio, hb_work_private_t *pv, uint8_t *data, int size );
117 static hb_buffer_t *link_buf_list( hb_work_private_t *pv );
118
119
120 static int64_t heap_pop( pts_heap_t *heap )
121 {
122     int64_t result;
123
124     if ( heap->nheap <= 0 )
125     {
126         return -1;
127     }
128
129     // return the top of the heap then put the bottom element on top,
130     // decrease the heap size by one & rebalence the heap.
131     result = heap->h[1];
132
133     int64_t v = heap->h[heap->nheap--];
134     int parent = 1;
135     int child = parent << 1;
136     while ( child <= heap->nheap )
137     {
138         // find the smallest of the two children of parent
139         if (child < heap->nheap && heap->h[child] > heap->h[child+1] )
140             ++child;
141
142         if (v <= heap->h[child])
143             // new item is smaller than either child so it's the new parent.
144             break;
145
146         // smallest child is smaller than new item so move it up then
147         // check its children.
148         int64_t hp = heap->h[child];
149         heap->h[parent] = hp;
150         parent = child;
151         child = parent << 1;
152     }
153     heap->h[parent] = v;
154     return result;
155 }
156
157 static void heap_push( pts_heap_t *heap, int64_t v )
158 {
159     if ( heap->nheap < HEAP_SIZE )
160     {
161         ++heap->nheap;
162     }
163
164     // stick the new value on the bottom of the heap then bubble it
165     // up to its correct spot.
166         int child = heap->nheap;
167         while (child > 1) {
168                 int parent = child >> 1;
169                 if (heap->h[parent] <= v)
170                         break;
171                 // move parent down
172                 int64_t hp = heap->h[parent];
173                 heap->h[child] = hp;
174                 child = parent;
175         }
176         heap->h[child] = v;
177 }
178
179
180 /***********************************************************************
181  * hb_work_decavcodec_init
182  ***********************************************************************
183  *
184  **********************************************************************/
185 static int decavcodecInit( hb_work_object_t * w, hb_job_t * job )
186 {
187     AVCodec * codec;
188
189     hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
190     w->private_data = pv;
191
192     pv->job   = job;
193     pv->list  = hb_list_init();
194
195     int codec_id = w->codec_param;
196     /*XXX*/
197     if ( codec_id == 0 )
198         codec_id = CODEC_ID_MP2;
199
200     codec = avcodec_find_decoder( codec_id );
201     pv->parser = av_parser_init( codec_id );
202
203     pv->context = avcodec_alloc_context();
204     hb_avcodec_open( pv->context, codec );
205
206     if ( w->audio != NULL &&
207          hb_need_downmix( w->audio->config.in.channel_layout, 
208                           w->audio->config.out.mixdown) )
209     {
210         pv->downmix = hb_downmix_init(w->audio->config.in.channel_layout, 
211                                       w->audio->config.out.mixdown);
212         hb_downmix_set_chan_map( pv->downmix, &hb_smpte_chan_map, &hb_qt_chan_map );
213         if ( w->audio->config.out.codec == HB_ACODEC_LAME )
214             hb_downmix_adjust_level( pv->downmix );
215     }
216
217     return 0;
218 }
219
220 /***********************************************************************
221  * Close
222  ***********************************************************************
223  *
224  **********************************************************************/
225 static void decavcodecClose( hb_work_object_t * w )
226 {
227     hb_work_private_t * pv = w->private_data;
228
229     if ( pv )
230     {
231         if ( pv->job && pv->context && pv->context->codec )
232         {
233             hb_log( "%s-decoder done: %u frames, %u decoder errors, %u drops",
234                     pv->context->codec->name, pv->nframes, pv->decode_errors,
235                     pv->ndrops );
236         }
237         if ( pv->sws_context )
238         {
239             sws_freeContext( pv->sws_context );
240         }
241         if ( pv->parser )
242         {
243             av_parser_close(pv->parser);
244         }
245         if ( pv->context && pv->context->codec )
246         {
247             hb_avcodec_close( pv->context );
248         }
249         if ( pv->list )
250         {
251             hb_list_close( &pv->list );
252         }
253         if ( pv->buffer )
254         {
255             av_free( pv->buffer );
256             pv->buffer = NULL;
257         }
258         if ( pv->downmix )
259         {
260             hb_downmix_close( &(pv->downmix) );
261         }
262         if ( pv->downmix_buffer )
263         {
264             free( pv->downmix_buffer );
265             pv->downmix_buffer = NULL;
266         }
267         free( pv );
268         w->private_data = NULL;
269     }
270 }
271
272 /***********************************************************************
273  * Work
274  ***********************************************************************
275  *
276  **********************************************************************/
277 static int decavcodecWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
278                     hb_buffer_t ** buf_out )
279 {
280     hb_work_private_t * pv = w->private_data;
281     hb_buffer_t * in = *buf_in;
282
283     if ( in->size <= 0 )
284     {
285         /* EOF on input stream - send it downstream & say that we're done */
286         *buf_out = in;
287         *buf_in = NULL;
288         return HB_WORK_DONE;
289     }
290
291     *buf_out = NULL;
292
293     if ( in->start < -1 && pv->pts_next <= 0 )
294     {
295         // discard buffers that start before video time 0
296         return HB_WORK_OK;
297     }
298
299     // if the packet has a timestamp use it 
300     if ( in->start != -1 )
301     {
302         pv->pts_next = in->start;
303     }
304
305     int pos, len;
306     for ( pos = 0; pos < in->size; pos += len )
307     {
308         uint8_t *parser_output_buffer;
309         int parser_output_buffer_len;
310         int64_t cur = pv->pts_next;
311
312         if ( pv->parser != NULL )
313         {
314             len = av_parser_parse2( pv->parser, pv->context,
315                     &parser_output_buffer, &parser_output_buffer_len,
316                     in->data + pos, in->size - pos, cur, cur, AV_NOPTS_VALUE );
317         }
318         else
319         {
320             parser_output_buffer = in->data;
321             len = parser_output_buffer_len = in->size;
322         }
323         if (parser_output_buffer_len)
324         {
325             // set the duration on every frame since the stream format can
326             // change (it shouldn't but there's no way to guarantee it).
327             // duration is a scaling factor to go from #bytes in the decoded
328             // frame to frame time (in 90KHz mpeg ticks). 'channels' converts
329             // total samples to per-channel samples. 'sample_rate' converts
330             // per-channel samples to seconds per sample and the 90000
331             // is mpeg ticks per second.
332             if ( pv->context->sample_rate && pv->context->channels )
333             {
334                 pv->duration = 90000. /
335                             (double)( pv->context->sample_rate * pv->context->channels );
336             }
337             decodeAudio( w->audio, pv, parser_output_buffer, parser_output_buffer_len );
338         }
339     }
340     *buf_out = link_buf_list( pv );
341     return HB_WORK_OK;
342 }
343
344 static int decavcodecInfo( hb_work_object_t *w, hb_work_info_t *info )
345 {
346     hb_work_private_t *pv = w->private_data;
347
348     memset( info, 0, sizeof(*info) );
349
350     if ( pv && pv->context )
351     {
352         AVCodecContext *context = pv->context;
353         info->bitrate = context->bit_rate;
354         info->rate = context->time_base.num;
355         info->rate_base = context->time_base.den;
356         info->profile = context->profile;
357         info->level = context->level;
358         return 1;
359     }
360     return 0;
361 }
362
363 static int decavcodecBSInfo( hb_work_object_t *w, const hb_buffer_t *buf,
364                              hb_work_info_t *info )
365 {
366     hb_work_private_t *pv = w->private_data;
367     int ret = 0;
368
369     memset( info, 0, sizeof(*info) );
370
371     if ( pv && pv->context )
372     {
373         return decavcodecInfo( w, info );
374     }
375     // XXX
376     // We should parse the bitstream to find its parameters but for right
377     // now we just return dummy values if there's a codec that will handle it.
378     AVCodec *codec = avcodec_find_decoder( w->codec_param? w->codec_param :
379                                                            CODEC_ID_MP2 );
380     if ( ! codec )
381     {
382         // there's no ffmpeg codec for this audio type - give up
383         return -1;
384     }
385
386     static char codec_name[64];
387     info->name =  strncpy( codec_name, codec->name, sizeof(codec_name)-1 );
388
389     AVCodecParserContext *parser = av_parser_init( codec->id );
390     AVCodecContext *context = avcodec_alloc_context();
391     hb_avcodec_open( context, codec );
392     uint8_t *buffer = av_malloc( AVCODEC_MAX_AUDIO_FRAME_SIZE );
393     int out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
394     unsigned char *pbuffer;
395     int pos, pbuffer_size;
396
397     while ( buf && !ret )
398     {
399         pos = 0;
400         while ( pos < buf->size )
401         {
402             int len;
403
404             if (parser != NULL )
405             {
406                 len = av_parser_parse2( parser, context, &pbuffer, 
407                                         &pbuffer_size, buf->data + pos, 
408                                         buf->size - pos, buf->start, 
409                                         buf->start, AV_NOPTS_VALUE );
410             }
411             else
412             {
413                 pbuffer = buf->data;
414                 len = pbuffer_size = buf->size;
415             }
416             pos += len;
417             if ( pbuffer_size > 0 )
418             {
419                 AVPacket avp;
420                 av_init_packet( &avp );
421                 avp.data = pbuffer;
422                 avp.size = pbuffer_size;
423
424                 len = avcodec_decode_audio3( context, (int16_t*)buffer, 
425                                              &out_size, &avp );
426                 if ( len > 0 && context->sample_rate > 0 )
427                 {
428                     info->bitrate = context->bit_rate;
429                     info->rate = context->sample_rate;
430                     info->rate_base = 1;
431                     info->channel_layout = 
432                         hb_ff_layout_xlat(context->channel_layout, 
433                                           context->channels);
434                     ret = 1;
435                     break;
436                 }
437             }
438         }
439         buf = buf->next;
440     }
441
442     av_free( buffer );
443     if ( parser != NULL )
444         av_parser_close( parser );
445     hb_avcodec_close( context );
446     return ret;
447 }
448
449 /* -------------------------------------------------------------
450  * General purpose video decoder using libavcodec
451  */
452
453 static uint8_t *copy_plane( uint8_t *dst, uint8_t* src, int dstride, int sstride,
454                             int h )
455 {
456     if ( dstride == sstride )
457     {
458         memcpy( dst, src, dstride * h );
459         return dst + dstride * h;
460     }
461     int lbytes = dstride <= sstride? dstride : sstride;
462     while ( --h >= 0 )
463     {
464         memcpy( dst, src, lbytes );
465         src += sstride;
466         dst += dstride;
467     }
468     return dst;
469 }
470
471 // copy one video frame into an HB buf. If the frame isn't in our color space
472 // or at least one of its dimensions is odd, use sws_scale to convert/rescale it.
473 // Otherwise just copy the bits.
474 static hb_buffer_t *copy_frame( hb_work_private_t *pv, AVFrame *frame )
475 {
476     AVCodecContext *context = pv->context;
477     int w, h;
478     if ( ! pv->job )
479     {
480         // if the dimensions are odd, drop the lsb since h264 requires that
481         // both width and height be even.
482         w = ( context->width >> 1 ) << 1;
483         h = ( context->height >> 1 ) << 1;
484     }
485     else
486     {
487         w =  pv->job->title->width;
488         h =  pv->job->title->height;
489     }
490     hb_buffer_t *buf = hb_video_buffer_init( w, h );
491     uint8_t *dst = buf->data;
492
493     if ( context->pix_fmt != PIX_FMT_YUV420P || w != context->width ||
494          h != context->height )
495     {
496         // have to convert to our internal color space and/or rescale
497         AVPicture dstpic;
498         avpicture_fill( &dstpic, dst, PIX_FMT_YUV420P, w, h );
499
500         if ( ! pv->sws_context )
501         {
502             pv->sws_context = sws_getContext( context->width, context->height, context->pix_fmt,
503                                               w, h, PIX_FMT_YUV420P,
504                                               SWS_LANCZOS|SWS_ACCURATE_RND,
505                                               NULL, NULL, NULL );
506         }
507         sws_scale( pv->sws_context, frame->data, frame->linesize, 0, h,
508                    dstpic.data, dstpic.linesize );
509     }
510     else
511     {
512         dst = copy_plane( dst, frame->data[0], w, frame->linesize[0], h );
513         w = (w + 1) >> 1; h = (h + 1) >> 1;
514         dst = copy_plane( dst, frame->data[1], w, frame->linesize[1], h );
515         dst = copy_plane( dst, frame->data[2], w, frame->linesize[2], h );
516     }
517     return buf;
518 }
519
520 static int get_frame_buf( AVCodecContext *context, AVFrame *frame )
521 {
522     hb_work_private_t *pv = context->opaque;
523     frame->pts = pv->pts;
524     pv->pts = -1;
525     return avcodec_default_get_buffer( context, frame );
526 }
527
528 static int reget_frame_buf( AVCodecContext *context, AVFrame *frame )
529 {
530     hb_work_private_t *pv = context->opaque;
531     frame->pts = pv->pts;
532     pv->pts = -1;
533     return avcodec_default_reget_buffer( context, frame );
534 }
535
536 static void log_chapter( hb_work_private_t *pv, int chap_num, int64_t pts )
537 {
538     hb_chapter_t *c = hb_list_item( pv->job->title->list_chapter, chap_num - 1 );
539     if ( c && c->title )
540     {
541         hb_log( "%s: \"%s\" (%d) at frame %u time %"PRId64,
542                 pv->context->codec->name, c->title, chap_num, pv->nframes, pts );
543     }
544     else
545     {
546         hb_log( "%s: Chapter %d at frame %u time %"PRId64,
547                 pv->context->codec->name, chap_num, pv->nframes, pts );
548     }
549 }
550
551 static void flushDelayQueue( hb_work_private_t *pv )
552 {
553     hb_buffer_t *buf;
554     int slot = pv->nframes & (HEAP_SIZE-1);
555
556     // flush all the video packets left on our timestamp-reordering delay q
557     while ( ( buf = pv->delayq[slot] ) != NULL )
558     {
559         buf->start = heap_pop( &pv->pts_heap );
560         hb_list_add( pv->list, buf );
561         pv->delayq[slot] = NULL;
562         slot = ( slot + 1 ) & (HEAP_SIZE-1);
563     }
564 }
565
566 static int decodeFrame( hb_work_private_t *pv, uint8_t *data, int size )
567 {
568     int got_picture, oldlevel = 0;
569     AVFrame frame;
570     AVPacket avp;
571
572     if ( global_verbosity_level <= 1 )
573     {
574         oldlevel = av_log_get_level();
575         av_log_set_level( AV_LOG_QUIET );
576     }
577
578     av_init_packet( &avp );
579     avp.data = data;
580     avp.size = size;
581     if ( avcodec_decode_video2( pv->context, &frame, &got_picture, &avp ) < 0 )
582     {
583         ++pv->decode_errors;     
584     }
585     if ( global_verbosity_level <= 1 )
586     {
587         av_log_set_level( oldlevel );
588     }
589     if( got_picture )
590     {
591         // ffmpeg makes it hard to attach a pts to a frame. if the MPEG ES
592         // packet had a pts we handed it to av_parser_parse (if the packet had
593         // no pts we set it to -1 but before the parse we can't distinguish between
594         // the start of a video frame with no pts & an intermediate packet of
595         // some frame which never has a pts). we hope that when parse returns
596         // the frame to us the pts we originally handed it will be in parser->pts.
597         // we put this pts into pv->pts so that when a avcodec_decode_video
598         // finally gets around to allocating an AVFrame to hold the decoded
599         // frame we can stuff that pts into the frame. if all of these relays
600         // worked at this point frame.pts should hold the frame's pts from the
601         // original data stream or -1 if it didn't have one. in the latter case
602         // we generate the next pts in sequence for it.
603         double frame_dur = pv->duration;
604         if ( frame_dur <= 0 )
605         {
606             frame_dur = 90000. * (double)pv->context->time_base.num /
607                         (double)pv->context->time_base.den;
608             pv->duration = frame_dur;
609         }
610         if ( frame.repeat_pict )
611         {
612             frame_dur += frame.repeat_pict * frame_dur * 0.5;
613         }
614         // XXX Unlike every other video decoder, the Raw decoder doesn't
615         //     use the standard buffer allocation routines so we never
616         //     get to put a PTS in the frame. Do it now.
617         if ( pv->context->codec_id == CODEC_ID_RAWVIDEO )
618         {
619             frame.pts = pv->pts;
620             pv->pts = -1;
621         }
622         // If there was no pts for this frame, assume constant frame rate
623         // video & estimate the next frame time from the last & duration.
624         double pts = frame.pts;
625         if ( pts < 0 )
626         {
627             pts = pv->pts_next;
628         }
629         pv->pts_next = pts + frame_dur;
630
631         hb_buffer_t *buf;
632
633         // if we're doing a scan or this content couldn't have been broken
634         // by Microsoft we don't worry about timestamp reordering
635         if ( ! pv->job || ! pv->brokenByMicrosoft )
636         {
637             buf = copy_frame( pv, &frame );
638             buf->start = pts;
639             hb_list_add( pv->list, buf );
640             ++pv->nframes;
641             return got_picture;
642         }
643
644         // XXX This following probably addresses a libavcodec bug but I don't
645         //     see an easy fix so we workaround it here.
646         //
647         // The M$ 'packed B-frames' atrocity results in decoded frames with
648         // the wrong timestamp. E.g., if there are 2 b-frames the timestamps
649         // we see here will be "2 3 1 5 6 4 ..." instead of "1 2 3 4 5 6".
650         // The frames are actually delivered in the right order but with
651         // the wrong timestamp. To get the correct timestamp attached to
652         // each frame we have a delay queue (longer than the max number of
653         // b-frames) & a sorting heap for the timestamps. As each frame
654         // comes out of the decoder the oldest frame in the queue is removed
655         // and associated with the smallest timestamp. Then the new frame is
656         // added to the queue & its timestamp is pushed on the heap.
657         // This does nothing if the timestamps are correct (i.e., the video
658         // uses a codec that Micro$oft hasn't broken yet) but the frames
659         // get timestamped correctly even when M$ has munged them.
660
661         // remove the oldest picture from the frame queue (if any) &
662         // give it the smallest timestamp from our heap. The queue size
663         // is a power of two so we get the slot of the oldest by masking
664         // the frame count & this will become the slot of the newest
665         // once we've removed & processed the oldest.
666         int slot = pv->nframes & (HEAP_SIZE-1);
667         if ( ( buf = pv->delayq[slot] ) != NULL )
668         {
669             buf->start = heap_pop( &pv->pts_heap );
670
671             if ( pv->new_chap && buf->start >= pv->chap_time )
672             {
673                 buf->new_chap = pv->new_chap;
674                 pv->new_chap = 0;
675                 pv->chap_time = 0;
676                 log_chapter( pv, buf->new_chap, buf->start );
677             }
678             else if ( pv->nframes == 0 )
679             {
680                 log_chapter( pv, pv->job->chapter_start, buf->start );
681             }
682             hb_list_add( pv->list, buf );
683         }
684
685         // add the new frame to the delayq & push its timestamp on the heap
686         pv->delayq[slot] = copy_frame( pv, &frame );
687         heap_push( &pv->pts_heap, pts );
688
689         ++pv->nframes;
690     }
691
692     return got_picture;
693 }
694
695 static void decodeVideo( hb_work_private_t *pv, uint8_t *data, int size,
696                          int64_t pts, int64_t dts )
697 {
698     /*
699      * The following loop is a do..while because we need to handle both
700      * data & the flush at the end (signaled by size=0). At the end there's
701      * generally a frame in the parser & one or more frames in the decoder
702      * (depending on the bframes setting).
703      */
704     int pos = 0;
705     do {
706         uint8_t *pout;
707         int pout_len;
708         int len = av_parser_parse2( pv->parser, pv->context, &pout, &pout_len,
709                                     data + pos, size - pos, pts, dts, AV_NOPTS_VALUE );
710         pos += len;
711
712         if ( pout_len > 0 )
713         {
714             pv->pts = pv->parser->pts;
715             decodeFrame( pv, pout, pout_len );
716         }
717     } while ( pos < size );
718
719     /* the stuff above flushed the parser, now flush the decoder */
720     if ( size <= 0 )
721     {
722         while ( decodeFrame( pv, NULL, 0 ) )
723         {
724         }
725         flushDelayQueue( pv );
726     }
727 }
728
729 static hb_buffer_t *link_buf_list( hb_work_private_t *pv )
730 {
731     hb_buffer_t *head = hb_list_item( pv->list, 0 );
732
733     if ( head )
734     {
735         hb_list_rem( pv->list, head );
736
737         hb_buffer_t *last = head, *buf;
738
739         while ( ( buf = hb_list_item( pv->list, 0 ) ) != NULL )
740         {
741             hb_list_rem( pv->list, buf );
742             last->next = buf;
743             last = buf;
744         }
745     }
746     return head;
747 }
748
749
750 static int decavcodecvInit( hb_work_object_t * w, hb_job_t * job )
751 {
752
753     hb_work_private_t *pv = calloc( 1, sizeof( hb_work_private_t ) );
754     w->private_data = pv;
755     pv->job   = job;
756     pv->list = hb_list_init();
757
758     int codec_id = w->codec_param;
759     pv->parser = av_parser_init( codec_id );
760     pv->context = avcodec_alloc_context2( CODEC_TYPE_VIDEO );
761
762     /* we have to wrap ffmpeg's get_buffer to be able to set the pts (?!) */
763     pv->context->opaque = pv;
764     pv->context->get_buffer = get_frame_buf;
765     pv->context->reget_buffer = reget_frame_buf;
766
767     return 0;
768 }
769
770 static int next_hdr( hb_buffer_t *in, int offset )
771 {
772     uint8_t *dat = in->data;
773     uint16_t last2 = 0xffff;
774     for ( ; in->size - offset > 1; ++offset )
775     {
776         if ( last2 == 0 && dat[offset] == 0x01 )
777             // found an mpeg start code
778             return offset - 2;
779
780         last2 = ( last2 << 8 ) | dat[offset];
781     }
782
783     return -1;
784 }
785
786 static int find_hdr( hb_buffer_t *in, int offset, uint8_t hdr_type )
787 {
788     if ( in->size - offset < 4 )
789         // not enough room for an mpeg start code
790         return -1;
791
792     for ( ; ( offset = next_hdr( in, offset ) ) >= 0; ++offset )
793     {
794         if ( in->data[offset+3] == hdr_type )
795             // found it
796             break;
797     }
798     return offset;
799 }
800
801 static int setup_extradata( hb_work_object_t *w, hb_buffer_t *in )
802 {
803     hb_work_private_t *pv = w->private_data;
804
805     // we can't call the avstream funcs but the read_header func in the
806     // AVInputFormat may set up some state in the AVContext. In particular 
807     // vc1t_read_header allocates 'extradata' to deal with header issues
808     // related to Microsoft's bizarre engineering notions. We alloc a chunk
809     // of space to make vc1 work then associate the codec with the context.
810     if ( w->codec_param != CODEC_ID_VC1 )
811     {
812         // we haven't been inflicted with M$ - allocate a little space as
813         // a marker and return success.
814         pv->context->extradata_size = 16;
815         pv->context->extradata = av_malloc(pv->context->extradata_size);
816         return 0;
817     }
818
819     // find the start and and of the sequence header
820     int shdr, shdr_end;
821     if ( ( shdr = find_hdr( in, 0, 0x0f ) ) < 0 )
822     {
823         // didn't find start of seq hdr
824         return 1;
825     }
826     if ( ( shdr_end = next_hdr( in, shdr + 4 ) ) < 0 )
827     {
828         shdr_end = in->size;
829     }
830     shdr_end -= shdr;
831
832     // find the start and and of the entry point header
833     int ehdr, ehdr_end;
834     if ( ( ehdr = find_hdr( in, 0, 0x0e ) ) < 0 )
835     {
836         // didn't find start of entry point hdr
837         return 1;
838     }
839     if ( ( ehdr_end = next_hdr( in, ehdr + 4 ) ) < 0 )
840     {
841         ehdr_end = in->size;
842     }
843     ehdr_end -= ehdr;
844
845     // found both headers - allocate an extradata big enough to hold both
846     // then copy them into it.
847     pv->context->extradata_size = shdr_end + ehdr_end;
848     pv->context->extradata = av_malloc(pv->context->extradata_size + 8);
849     memcpy( pv->context->extradata, in->data + shdr, shdr_end );
850     memcpy( pv->context->extradata + shdr_end, in->data + ehdr, ehdr_end );
851     memset( pv->context->extradata + shdr_end + ehdr_end, 0, 8);
852     return 0;
853 }
854
855 static int decavcodecvWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
856                             hb_buffer_t ** buf_out )
857 {
858     hb_work_private_t *pv = w->private_data;
859     hb_buffer_t *in = *buf_in;
860     int64_t pts = AV_NOPTS_VALUE;
861     int64_t dts = pts;
862
863     *buf_in = NULL;
864
865     /* if we got an empty buffer signaling end-of-stream send it downstream */
866     if ( in->size == 0 )
867     {
868         decodeVideo( pv, in->data, in->size, pts, dts );
869         hb_list_add( pv->list, in );
870         *buf_out = link_buf_list( pv );
871         return HB_WORK_DONE;
872     }
873
874     // if this is the first frame open the codec (we have to wait for the
875     // first frame because of M$ VC1 braindamage).
876     if ( pv->context->extradata_size == 0 )
877     {
878         if ( setup_extradata( w, in ) )
879         {
880             // we didn't find the headers needed to set up extradata.
881             // the codec will abort if we open it so just free the buf
882             // and hope we eventually get the info we need.
883             hb_buffer_close( &in );
884             return HB_WORK_OK;
885         }
886         AVCodec *codec = avcodec_find_decoder( w->codec_param );
887         // There's a mis-feature in ffmpeg that causes the context to be 
888         // incorrectly initialized the 1st time avcodec_open is called.
889         // If you close it and open a 2nd time, it finishes the job.
890         hb_avcodec_open( pv->context, codec );
891         hb_avcodec_close( pv->context );
892         hb_avcodec_open( pv->context, codec );
893     }
894
895     if( in->start >= 0 )
896     {
897         pts = in->start;
898         dts = in->renderOffset;
899     }
900     if ( in->new_chap )
901     {
902         pv->new_chap = in->new_chap;
903         pv->chap_time = pts >= 0? pts : pv->pts_next;
904     }
905     decodeVideo( pv, in->data, in->size, pts, dts );
906     hb_buffer_close( &in );
907     *buf_out = link_buf_list( pv );
908     return HB_WORK_OK;
909 }
910
911 static int decavcodecvInfo( hb_work_object_t *w, hb_work_info_t *info )
912 {
913     hb_work_private_t *pv = w->private_data;
914
915     memset( info, 0, sizeof(*info) );
916
917     if ( pv && pv->context )
918     {
919         AVCodecContext *context = pv->context;
920         info->bitrate = context->bit_rate;
921         info->width = context->width;
922         info->height = context->height;
923
924         /* ffmpeg gives the frame rate in frames per second while HB wants
925          * it in units of the 27MHz MPEG clock. */
926         info->rate = 27000000;
927         info->rate_base = (int64_t)context->time_base.num * 27000000LL /
928                           context->time_base.den;
929         if ( context->ticks_per_frame > 1 )
930         {
931             // for ffmpeg 0.5 & later, the H.264 & MPEG-2 time base is
932             // field rate rather than frame rate so convert back to frames.
933             info->rate_base *= context->ticks_per_frame;
934         }
935         
936         info->pixel_aspect_width = context->sample_aspect_ratio.num;
937         info->pixel_aspect_height = context->sample_aspect_ratio.den;
938
939         /* Sometimes there's no pixel aspect set in the source ffmpeg context
940          * which appears to come from the video stream. In that case,
941          * try the pixel aspect in AVStream (which appears to come from
942          * the container). Else assume a 1:1 PAR. */
943         if ( info->pixel_aspect_width == 0 ||
944              info->pixel_aspect_height == 0 )
945         {
946             AVStream *st = hb_ffmpeg_avstream( w->codec_param );
947             info->pixel_aspect_width = st->sample_aspect_ratio.num ?
948                                         st->sample_aspect_ratio.num : 1;
949             info->pixel_aspect_height = st->sample_aspect_ratio.den ?
950                                         st->sample_aspect_ratio.den : 1;
951         }
952         /* ffmpeg returns the Pixel Aspect Ratio (PAR). Handbrake wants the
953          * Display Aspect Ratio so we convert by scaling by the Storage
954          * Aspect Ratio (w/h). We do the calc in floating point to get the
955          * rounding right. */
956         info->aspect = (double)info->pixel_aspect_width * 
957                        (double)context->width /
958                        (double)info->pixel_aspect_height /
959                        (double)context->height;
960
961         info->profile = context->profile;
962         info->level = context->level;
963         info->name = context->codec->name;
964         return 1;
965     }
966     return 0;
967 }
968
969 static int decavcodecvBSInfo( hb_work_object_t *w, const hb_buffer_t *buf,
970                              hb_work_info_t *info )
971 {
972     return 0;
973 }
974
975 hb_work_object_t hb_decavcodecv =
976 {
977     WORK_DECAVCODECV,
978     "Video decoder (libavcodec)",
979     decavcodecvInit,
980     decavcodecvWork,
981     decavcodecClose,
982     decavcodecvInfo,
983     decavcodecvBSInfo
984 };
985
986
987 // This is a special decoder for ffmpeg streams. The ffmpeg stream reader
988 // includes a parser and passes information from the parser to the decoder
989 // via a codec context kept in the AVStream of the reader's AVFormatContext.
990 // We *have* to use that codec context to decode the stream or we'll get
991 // garbage. ffmpeg_title_scan put a cookie that can be used to get to that
992 // codec context in our codec_param.
993
994 // this routine gets the appropriate context pointer from the ffmpeg
995 // stream reader. it can't be called until we get the first buffer because
996 // we can't guarantee that reader will be called before the our init
997 // routine and if our init is called first we'll get a pointer to the
998 // old scan stream (which has already been closed).
999 static void init_ffmpeg_context( hb_work_object_t *w )
1000 {
1001     hb_work_private_t *pv = w->private_data;
1002     pv->context = hb_ffmpeg_context( w->codec_param );
1003
1004     // during scan the decoder gets closed & reopened which will
1005     // close the codec so reopen it if it's not there
1006     if ( ! pv->context->codec )
1007     {
1008         AVCodec *codec = avcodec_find_decoder( pv->context->codec_id );
1009         hb_avcodec_open( pv->context, codec );
1010     }
1011     // set up our best guess at the frame duration.
1012     // the frame rate in the codec is usually bogus but it's sometimes
1013     // ok in the stream.
1014     AVStream *st = hb_ffmpeg_avstream( w->codec_param );
1015
1016     if ( st->nb_frames && st->duration )
1017     {
1018         // compute the average frame duration from the total number
1019         // of frames & the total duration.
1020         pv->duration = ( (double)st->duration * (double)st->time_base.num ) /
1021                        ( (double)st->nb_frames * (double)st->time_base.den );
1022     }
1023     else
1024     {
1025         // XXX We don't have a frame count or duration so try to use the
1026         // far less reliable time base info in the stream.
1027         // Because the time bases are so screwed up, we only take values
1028         // in the range 8fps - 64fps.
1029         AVRational tb;
1030         if ( st->avg_frame_rate.den * 64 > st->avg_frame_rate.num &&
1031              st->avg_frame_rate.num > st->avg_frame_rate.den * 8 )
1032         {
1033             tb.num = st->avg_frame_rate.den;
1034             tb.den = st->avg_frame_rate.num;
1035         }
1036         else if ( st->time_base.num * 64 > st->time_base.den &&
1037                   st->time_base.den > st->time_base.num * 8 )
1038         {
1039             tb = st->time_base;
1040         }
1041         else if ( st->r_frame_rate.den * 64 > st->r_frame_rate.num &&
1042                   st->r_frame_rate.num > st->r_frame_rate.den * 8 )
1043         {
1044             tb.num = st->r_frame_rate.den;
1045             tb.den = st->r_frame_rate.num;
1046         }
1047         else
1048         {
1049             tb.num = 1001;  /*XXX*/
1050             tb.den = 24000; /*XXX*/
1051         }
1052         pv->duration =  (double)tb.num / (double)tb.den;
1053     }
1054     pv->duration *= 90000.;
1055
1056     // we have to wrap ffmpeg's get_buffer to be able to set the pts (?!)
1057     pv->context->opaque = pv;
1058     pv->context->get_buffer = get_frame_buf;
1059     pv->context->reget_buffer = reget_frame_buf;
1060
1061     // avi, mkv and possibly mp4 containers can contain the M$ VFW packed
1062     // b-frames abortion that messes up frame ordering and timestamps.
1063     // XXX ffmpeg knows which streams are broken but doesn't expose the
1064     //     info externally. We should patch ffmpeg to add a flag to the
1065     //     codec context for this but until then we mark all ffmpeg streams
1066     //     as suspicious.
1067     pv->brokenByMicrosoft = 1;
1068 }
1069
1070 static void prepare_ffmpeg_buffer( hb_buffer_t * in )
1071 {
1072     // ffmpeg requires an extra 8 bytes of zero at the end of the buffer and
1073     // will seg fault in odd, data dependent ways if it's not there. (my guess
1074     // is this is a case of a local performance optimization creating a global
1075     // performance degradation since all the time wasted by extraneous data
1076     // copies & memory zeroing has to be huge compared to the minor reduction
1077     // in inner-loop instructions this affords - modern cpus bottleneck on
1078     // memory bandwidth not instruction bandwidth).
1079     if ( in->size + FF_INPUT_BUFFER_PADDING_SIZE > in->alloc )
1080     {
1081         // have to realloc to add the padding
1082         hb_buffer_realloc( in, in->size + FF_INPUT_BUFFER_PADDING_SIZE );
1083     }
1084     memset( in->data + in->size, 0, FF_INPUT_BUFFER_PADDING_SIZE );
1085 }
1086
1087 static int decavcodecviInit( hb_work_object_t * w, hb_job_t * job )
1088 {
1089
1090     hb_work_private_t *pv = calloc( 1, sizeof( hb_work_private_t ) );
1091     w->private_data = pv;
1092     pv->job   = job;
1093     pv->list = hb_list_init();
1094     pv->pts_next = -1;
1095     pv->pts = -1;
1096
1097     if ( w->audio != NULL &&
1098          hb_need_downmix( w->audio->config.in.channel_layout, 
1099                           w->audio->config.out.mixdown) )
1100     {
1101         pv->downmix = hb_downmix_init(w->audio->config.in.channel_layout, 
1102                                       w->audio->config.out.mixdown);
1103         hb_downmix_set_chan_map( pv->downmix, &hb_smpte_chan_map, &hb_qt_chan_map );
1104         if ( w->audio->config.out.codec == HB_ACODEC_LAME )
1105             hb_downmix_adjust_level( pv->downmix );
1106     }
1107
1108     return 0;
1109 }
1110
1111 static int decavcodecviWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
1112                              hb_buffer_t ** buf_out )
1113 {
1114     hb_work_private_t *pv = w->private_data;
1115     hb_buffer_t *in = *buf_in;
1116     *buf_in = NULL;
1117
1118     /* if we got an empty buffer signaling end-of-stream send it downstream */
1119     if ( in->size == 0 )
1120     {
1121         /* flush any frames left in the decoder */
1122         while ( pv->context && decodeFrame( pv, NULL, 0 ) )
1123         {
1124         }
1125         flushDelayQueue( pv );
1126         hb_list_add( pv->list, in );
1127         *buf_out = link_buf_list( pv );
1128         return HB_WORK_DONE;
1129     }
1130
1131     if ( ! pv->context )
1132     {
1133         init_ffmpeg_context( w );
1134     }
1135
1136     int64_t pts = in->start;
1137     if( pts >= 0 )
1138     {
1139         // use the first timestamp as our 'next expected' pts
1140         if ( pv->pts_next < 0 )
1141         {
1142             pv->pts_next = pts;
1143         }
1144         pv->pts = pts;
1145     }
1146
1147     if ( in->new_chap )
1148     {
1149         pv->new_chap = in->new_chap;
1150         pv->chap_time = pts >= 0? pts : pv->pts_next;
1151     }
1152     prepare_ffmpeg_buffer( in );
1153     decodeFrame( pv, in->data, in->size );
1154     hb_buffer_close( &in );
1155     *buf_out = link_buf_list( pv );
1156     return HB_WORK_OK;
1157 }
1158
1159 static int decavcodecviInfo( hb_work_object_t *w, hb_work_info_t *info )
1160 {
1161     if ( decavcodecvInfo( w, info ) )
1162     {
1163         hb_work_private_t *pv = w->private_data;
1164         if ( ! pv->context )
1165         {
1166             init_ffmpeg_context( w );
1167         }
1168         // we have the frame duration in units of the 90KHz pts clock but
1169         // need it in units of the 27MHz MPEG clock. */
1170         info->rate = 27000000;
1171         info->rate_base = pv->duration * 300.;
1172         return 1;
1173     }
1174     return 0;
1175 }
1176
1177 static void decodeAudio( hb_audio_t * audio, hb_work_private_t *pv, uint8_t *data, int size )
1178 {
1179     AVCodecContext *context = pv->context;
1180     int pos = 0;
1181     int loop_limit = 256;
1182
1183     while ( pos < size )
1184     {
1185         int16_t *buffer = pv->buffer;
1186         if ( buffer == NULL )
1187         {
1188             pv->buffer = av_malloc( AVCODEC_MAX_AUDIO_FRAME_SIZE );
1189             buffer = pv->buffer;
1190         }
1191
1192         AVPacket avp;
1193         av_init_packet( &avp );
1194         avp.data = data + pos;
1195         avp.size = size - pos;
1196
1197         int out_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
1198         int nsamples;
1199         int len = avcodec_decode_audio3( context, buffer, &out_size, &avp );
1200         if ( len < 0 )
1201         {
1202             return;
1203         }
1204         if ( len == 0 )
1205         {
1206             if ( !(loop_limit--) )
1207                 return;
1208         }
1209         else
1210             loop_limit = 256;
1211
1212         pos += len;
1213         if( out_size > 0 )
1214         {
1215             // We require signed 16-bit ints for the output format. If
1216             // we got something different convert it.
1217             if ( context->sample_fmt != SAMPLE_FMT_S16 )
1218             {
1219                 // Note: av_audio_convert seems to be a work-in-progress but
1220                 //       looks like it will eventually handle general audio
1221                 //       mixdowns which would allow us much more flexibility
1222                 //       in handling multichannel audio in HB. If we were doing
1223                 //       anything more complicated than a one-for-one format
1224                 //       conversion we'd probably want to cache the converter
1225                 //       context in the pv.
1226                 int isamp = av_get_bits_per_sample_format( context->sample_fmt ) / 8;
1227                 AVAudioConvert *ctx = av_audio_convert_alloc( SAMPLE_FMT_S16, 1,
1228                                                               context->sample_fmt, 1,
1229                                                               NULL, 0 );
1230                 // get output buffer size (in 2-byte samples) then malloc a buffer
1231                 nsamples = out_size / isamp;
1232                 buffer = av_malloc( nsamples * 2 );
1233
1234                 // we're doing straight sample format conversion which behaves as if
1235                 // there were only one channel.
1236                 const void * const ibuf[6] = { pv->buffer };
1237                 void * const obuf[6] = { buffer };
1238                 const int istride[6] = { isamp };
1239                 const int ostride[6] = { 2 };
1240
1241                 av_audio_convert( ctx, obuf, ostride, ibuf, istride, nsamples );
1242                 av_audio_convert_free( ctx );
1243             }
1244             else
1245             {
1246                 nsamples = out_size / 2;
1247             }
1248
1249             hb_buffer_t * buf;
1250
1251             if ( pv->downmix )
1252             {
1253                 pv->downmix_buffer = realloc(pv->downmix_buffer, nsamples * sizeof(hb_sample_t));
1254                 
1255                 int i;
1256                 for( i = 0; i < nsamples; ++i )
1257                 {
1258                     pv->downmix_buffer[i] = buffer[i];
1259                 }
1260
1261                 int n_ch_samples = nsamples / context->channels;
1262                 int channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(audio->config.out.mixdown);
1263
1264                 buf = hb_buffer_init( n_ch_samples * channels * sizeof(float) );
1265                 hb_sample_t *samples = (hb_sample_t *)buf->data;
1266                 hb_downmix(pv->downmix, samples, pv->downmix_buffer, n_ch_samples);
1267             }
1268             else
1269             {
1270                 buf = hb_buffer_init( nsamples * sizeof(float) );
1271                 float *fl32 = (float *)buf->data;
1272                 int i;
1273                 for( i = 0; i < nsamples; ++i )
1274                 {
1275                     fl32[i] = buffer[i];
1276                 }
1277                 int n_ch_samples = nsamples / context->channels;
1278                 hb_layout_remap( &hb_smpte_chan_map, &hb_qt_chan_map,
1279                                  audio->config.in.channel_layout, 
1280                                  fl32, n_ch_samples );
1281             }
1282
1283             double pts = pv->pts_next;
1284             buf->start = pts;
1285             pts += nsamples * pv->duration;
1286             buf->stop  = pts;
1287             pv->pts_next = pts;
1288
1289             hb_list_add( pv->list, buf );
1290
1291             // if we allocated a buffer for sample format conversion, free it
1292             if ( buffer != pv->buffer )
1293             {
1294                 av_free( buffer );
1295             }
1296         }
1297     }
1298 }
1299
1300 static int decavcodecaiWork( hb_work_object_t *w, hb_buffer_t **buf_in,
1301                     hb_buffer_t **buf_out )
1302 {
1303     if ( (*buf_in)->size <= 0 )
1304     {
1305         /* EOF on input stream - send it downstream & say that we're done */
1306         *buf_out = *buf_in;
1307         *buf_in = NULL;
1308         return HB_WORK_DONE;
1309     }
1310
1311     hb_work_private_t *pv = w->private_data;
1312
1313     if ( (*buf_in)->start < -1 && pv->pts_next <= 0 )
1314     {
1315         // discard buffers that start before video time 0
1316         *buf_out = NULL;
1317         return HB_WORK_OK;
1318     }
1319
1320     if ( ! pv->context )
1321     {
1322         init_ffmpeg_context( w );
1323         // duration is a scaling factor to go from #bytes in the decoded
1324         // frame to frame time (in 90KHz mpeg ticks). 'channels' converts
1325         // total samples to per-channel samples. 'sample_rate' converts
1326         // per-channel samples to seconds per sample and the 90000
1327         // is mpeg ticks per second.
1328         pv->duration = 90000. /
1329                     (double)( pv->context->sample_rate * pv->context->channels );
1330     }
1331     hb_buffer_t *in = *buf_in;
1332
1333     // if the packet has a timestamp use it if we don't have a timestamp yet
1334     // or if there's been a timing discontinuity of more than 100ms.
1335     if ( in->start >= 0 &&
1336          ( pv->pts_next < 0 || ( in->start - pv->pts_next ) > 90*100 ) )
1337     {
1338         pv->pts_next = in->start;
1339     }
1340     prepare_ffmpeg_buffer( in );
1341     decodeAudio( w->audio, pv, in->data, in->size );
1342     *buf_out = link_buf_list( pv );
1343
1344     return HB_WORK_OK;
1345 }
1346
1347 hb_work_object_t hb_decavcodecvi =
1348 {
1349     WORK_DECAVCODECVI,
1350     "Video decoder (ffmpeg streams)",
1351     decavcodecviInit,
1352     decavcodecviWork,
1353     decavcodecClose,
1354     decavcodecviInfo,
1355     decavcodecvBSInfo
1356 };
1357
1358 hb_work_object_t hb_decavcodecai =
1359 {
1360     WORK_DECAVCODECAI,
1361     "Audio decoder (ffmpeg streams)",
1362     decavcodecviInit,
1363     decavcodecaiWork,
1364     decavcodecClose,
1365     decavcodecInfo,
1366     decavcodecBSInfo
1367 };