OSDN Git Service

Keep track of the input pixel aspect ratio as well as the output one. Hopefully doesn...
[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 #include "hb.h"
8
9 #include "libavcodec/avcodec.h"
10 #include "libavformat/avformat.h"
11
12 static int  decavcodecInit( hb_work_object_t *, hb_job_t * );
13 static int  decavcodecWork( hb_work_object_t *, hb_buffer_t **, hb_buffer_t ** );
14 static void decavcodecClose( hb_work_object_t * );
15 static int decavcodecInfo( hb_work_object_t *, hb_work_info_t * );
16 static int decavcodecBSInfo( hb_work_object_t *, const hb_buffer_t *, hb_work_info_t * );
17
18 hb_work_object_t hb_decavcodec =
19 {
20     WORK_DECAVCODEC,
21     "MPGA decoder (libavcodec)",
22     decavcodecInit,
23     decavcodecWork,
24     decavcodecClose,
25     decavcodecInfo,
26     decavcodecBSInfo
27 };
28
29 struct hb_work_private_s
30 {
31     hb_job_t             *job;
32     AVCodecContext       *context;
33     AVCodecParserContext *parser;
34     hb_list_t            *list;
35     double               pts_next;  // next pts we expect to generate
36     int64_t              pts;       // (video) pts passing from parser to decoder
37     int64_t              chap_time; // time of next chap mark (if new_chap != 0)
38     int                  new_chap;
39     int                  ignore_pts; // workaround M$ bugs
40     int                  nframes;
41     int                  ndrops;
42     double               duration;  // frame duration (for video)
43 };
44
45
46
47 /***********************************************************************
48  * hb_work_decavcodec_init
49  ***********************************************************************
50  *
51  **********************************************************************/
52 static int decavcodecInit( hb_work_object_t * w, hb_job_t * job )
53 {
54     AVCodec * codec;
55
56     hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
57     w->private_data = pv;
58
59     pv->job   = job;
60
61     int codec_id = w->codec_param;
62     /*XXX*/
63     if ( codec_id == 0 )
64         codec_id = CODEC_ID_MP2;
65     codec = avcodec_find_decoder( codec_id );
66     pv->parser = av_parser_init( codec_id );
67
68     pv->context = avcodec_alloc_context();
69     avcodec_open( pv->context, codec );
70
71     return 0;
72 }
73
74 /***********************************************************************
75  * Close
76  ***********************************************************************
77  *
78  **********************************************************************/
79 static void decavcodecClose( hb_work_object_t * w )
80 {
81     hb_work_private_t * pv = w->private_data;
82     if ( pv->parser )
83         {
84                 av_parser_close(pv->parser);
85         }
86     if ( pv->context && pv->context->codec )
87     {
88         avcodec_close( pv->context );
89     }
90     if ( pv->list )
91     {
92         hb_list_close( &pv->list );
93     }
94 }
95
96 /***********************************************************************
97  * Work
98  ***********************************************************************
99  *
100  **********************************************************************/
101 static int decavcodecWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
102                     hb_buffer_t ** buf_out )
103 {
104     hb_work_private_t * pv = w->private_data;
105     hb_buffer_t * in = *buf_in, * buf, * last = NULL;
106     int   pos, len, out_size, i, uncompressed_len;
107     short buffer[AVCODEC_MAX_AUDIO_FRAME_SIZE];
108     uint64_t cur;
109     unsigned char *parser_output_buffer;
110     int parser_output_buffer_len;
111
112     *buf_out = NULL;
113
114     cur = ( in->start < 0 )? pv->pts_next : in->start;
115
116     pos = 0;
117     while( pos < in->size )
118     {
119         len = av_parser_parse( pv->parser, pv->context,
120                                &parser_output_buffer, &parser_output_buffer_len,
121                                in->data + pos, in->size - pos, cur, cur );
122         out_size = 0;
123         uncompressed_len = 0;
124         if (parser_output_buffer_len)
125         {
126             out_size = sizeof(buffer);
127             uncompressed_len = avcodec_decode_audio2( pv->context, buffer,
128                                                       &out_size,
129                                                       parser_output_buffer,
130                                                       parser_output_buffer_len );
131         }
132         if( out_size )
133         {
134             short * s16;
135             float * fl32;
136
137             buf = hb_buffer_init( 2 * out_size );
138
139             int sample_size_in_bytes = 2;   // Default to 2 bytes
140             switch (pv->context->sample_fmt)
141             {
142               case SAMPLE_FMT_S16:
143                 sample_size_in_bytes = 2;
144                 break;
145               /* We should handle other formats here - but that needs additional format conversion work below */
146               /* For now we'll just report the error and try to carry on */
147               default:
148                 hb_log("decavcodecWork - Unknown Sample Format from avcodec_decode_audio (%d) !", pv->context->sample_fmt);
149                 break;
150             }
151
152             buf->start = cur;
153             buf->stop  = cur + 90000 * ( out_size / (sample_size_in_bytes * pv->context->channels) ) /
154                          pv->context->sample_rate;
155             cur = buf->stop;
156
157             s16  = buffer;
158             fl32 = (float *) buf->data;
159             for( i = 0; i < out_size / 2; i++ )
160             {
161                 fl32[i] = s16[i];
162             }
163
164             if( last )
165             {
166                 last = last->next = buf;
167             }
168             else
169             {
170                 *buf_out = last = buf;
171             }
172         }
173
174         pos += len;
175     }
176
177     pv->pts_next = cur;
178
179     return HB_WORK_OK;
180 }
181
182 static int decavcodecInfo( hb_work_object_t *w, hb_work_info_t *info )
183 {
184     hb_work_private_t *pv = w->private_data;
185
186     memset( info, 0, sizeof(*info) );
187
188     if ( pv && pv->context )
189     {
190         AVCodecContext *context = pv->context;
191         info->bitrate = context->bit_rate;
192         info->rate = context->time_base.num;
193         info->rate_base = context->time_base.den;
194         info->profile = context->profile;
195         info->level = context->level;
196         return 1;
197     }
198     return 0;
199 }
200
201 static int decavcodecBSInfo( hb_work_object_t *w, const hb_buffer_t *buf,
202                              hb_work_info_t *info )
203 {
204     hb_work_private_t *pv = w->private_data;
205
206     memset( info, 0, sizeof(*info) );
207
208     if ( pv && pv->context )
209     {
210         return decavcodecInfo( w, info );
211     }
212     // XXX
213     // We should parse the bitstream to find its parameters but for right
214     // now we just return dummy values if there's a codec that will handle it.
215     AVCodec *codec = avcodec_find_decoder( w->codec_param? w->codec_param :
216                                                            CODEC_ID_MP2 );
217     if ( codec )
218     {
219         static char codec_name[64];
220
221         info->name =  strncpy( codec_name, codec->name, sizeof(codec_name)-1 );
222         info->bitrate = 384000;
223         info->rate = 48000;
224         info->rate_base = 1;
225         info->channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
226         return 1;
227     }
228     return -1;
229 }
230
231 /* -------------------------------------------------------------
232  * General purpose video decoder using libavcodec
233  */
234
235 static uint8_t *copy_plane( uint8_t *dst, uint8_t* src, int dstride, int sstride,
236                             int h )
237 {
238     if ( dstride == sstride )
239     {
240         memcpy( dst, src, dstride * h );
241         return dst + dstride * h;
242     }
243     int lbytes = dstride <= sstride? dstride : sstride;
244     while ( --h >= 0 )
245     {
246         memcpy( dst, src, lbytes );
247         src += sstride;
248         dst += dstride;
249     }
250     return dst;
251 }
252
253 /* Note: assumes frame format is PIX_FMT_YUV420P */
254 static hb_buffer_t *copy_frame( AVCodecContext *context, AVFrame *frame )
255 {
256     int w = context->width, h = context->height;
257     hb_buffer_t *buf = hb_buffer_init( w * h * 3 / 2 );
258     uint8_t *dst = buf->data;
259
260     dst = copy_plane( dst, frame->data[0], w, frame->linesize[0], h );
261     w >>= 1; h >>= 1;
262     dst = copy_plane( dst, frame->data[1], w, frame->linesize[1], h );
263     dst = copy_plane( dst, frame->data[2], w, frame->linesize[2], h );
264
265     return buf;
266 }
267
268 static int get_frame_buf( AVCodecContext *context, AVFrame *frame )
269 {
270     hb_work_private_t *pv = context->opaque;
271     frame->pts = pv->pts;
272     pv->pts = -1;
273
274     return avcodec_default_get_buffer( context, frame );
275 }
276
277 static void log_chapter( hb_work_private_t *pv, int chap_num, int64_t pts )
278 {
279     hb_chapter_t *c = hb_list_item( pv->job->title->list_chapter, chap_num - 1 );
280     hb_log( "%s: \"%s\" (%d) at frame %u time %lld", pv->context->codec->name,
281             c->title, chap_num, pv->nframes, pts );
282 }
283
284 static int decodeFrame( hb_work_private_t *pv, uint8_t *data, int size )
285 {
286     int got_picture;
287     AVFrame frame;
288
289     avcodec_decode_video( pv->context, &frame, &got_picture, data, size );
290     if( got_picture )
291     {
292         // ffmpeg makes it hard to attach a pts to a frame. if the MPEG ES
293         // packet had a pts we handed it to av_parser_parse (if the packet had
294         // no pts we set it to -1 but before the parse we can't distinguish between
295         // the start of a video frame with no pts & an intermediate packet of
296         // some frame which never has a pts). we hope that when parse returns
297         // the frame to us the pts we originally handed it will be in parser->pts.
298         // we put this pts into pv->pts so that when a avcodec_decode_video
299         // finally gets around to allocating an AVFrame to hold the decoded
300         // frame we can stuff that pts into the frame. if all of these relays
301         // worked at this point frame.pts should hold the frame's pts from the
302         // original data stream or -1 if it didn't have one. in the latter case
303         // we generate the next pts in sequence for it.
304         double pts = frame.pts;
305         if ( pts < 0 )
306         {
307             pts = pv->pts_next;
308         }
309         if ( pv->duration == 0 )
310         {
311             pv->duration = 90000. * pv->context->time_base.num /
312                            pv->context->time_base.den;
313         }
314         double frame_dur = pv->duration;
315         frame_dur += frame.repeat_pict * frame_dur * 0.5;
316         pv->pts_next = pts + frame_dur;
317
318         hb_buffer_t *buf = copy_frame( pv->context, &frame );
319         buf->start = pts;
320
321         if ( pv->new_chap && buf->start >= pv->chap_time )
322         {
323             buf->new_chap = pv->new_chap;
324             pv->new_chap = 0;
325             pv->chap_time = 0;
326             if ( pv->job )
327             {
328                 log_chapter( pv, buf->new_chap, buf->start );
329             }
330         }
331         else if ( pv->job && pv->nframes == 0 )
332         {
333             log_chapter( pv, pv->job->chapter_start, buf->start );
334         }
335         hb_list_add( pv->list, buf );
336         ++pv->nframes;
337     }
338     return got_picture;
339 }
340
341 static void decodeVideo( hb_work_private_t *pv, uint8_t *data, int size,
342                          int64_t pts, int64_t dts )
343 {
344     /*
345      * The following loop is a do..while because we need to handle both
346      * data & the flush at the end (signaled by size=0). At the end there's
347      * generally a frame in the parser & one or more frames in the decoder
348      * (depending on the bframes setting).
349      */
350     int pos = 0;
351     do {
352         uint8_t *pout;
353         int pout_len;
354         int len = av_parser_parse( pv->parser, pv->context, &pout, &pout_len,
355                                    data + pos, size - pos, pts, dts );
356         pos += len;
357
358         if ( pout_len > 0 )
359         {
360             pv->pts = pv->parser->pts;
361             decodeFrame( pv, pout, pout_len );
362         }
363     } while ( pos < size );
364
365     /* the stuff above flushed the parser, now flush the decoder */
366     while ( size == 0 && decodeFrame( pv, NULL, 0 ) )
367     {
368     }
369 }
370
371 static hb_buffer_t *link_buf_list( hb_work_private_t *pv )
372 {
373     hb_buffer_t *head = hb_list_item( pv->list, 0 );
374
375     if ( head )
376     {
377         hb_list_rem( pv->list, head );
378
379         hb_buffer_t *last = head, *buf;
380
381         while ( ( buf = hb_list_item( pv->list, 0 ) ) != NULL )
382         {
383             hb_list_rem( pv->list, buf );
384             last->next = buf;
385             last = buf;
386         }
387     }
388     return head;
389 }
390
391
392 static int decavcodecvInit( hb_work_object_t * w, hb_job_t * job )
393 {
394
395     hb_work_private_t *pv = calloc( 1, sizeof( hb_work_private_t ) );
396     w->private_data = pv;
397     pv->job   = job;
398     pv->list = hb_list_init();
399
400     int codec_id = w->codec_param;
401     pv->parser = av_parser_init( codec_id );
402     pv->context = avcodec_alloc_context2( CODEC_TYPE_VIDEO );
403
404     /* we have to wrap ffmpeg's get_buffer to be able to set the pts (?!) */
405     pv->context->opaque = pv;
406     pv->context->get_buffer = get_frame_buf;
407
408     AVCodec *codec = avcodec_find_decoder( codec_id );
409
410     // we can't call the avstream funcs but the read_header func in the
411     // AVInputFormat may set up some state in the AVContext. In particular 
412     // vc1t_read_header allocates 'extradata' to deal with header issues
413     // related to Microsoft's bizarre engineering notions. We alloc a chunk
414     // of space to make vc1 work then associate the codec with the context.
415     pv->context->extradata_size = 32;
416     pv->context->extradata = av_malloc(pv->context->extradata_size);
417     avcodec_open( pv->context, codec );
418
419     return 0;
420 }
421
422 static int decavcodecvWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
423                             hb_buffer_t ** buf_out )
424 {
425     hb_work_private_t *pv = w->private_data;
426     hb_buffer_t *in = *buf_in;
427     int64_t pts = -1;
428     int64_t dts = pts;
429
430     *buf_in = NULL;
431
432     /* if we got an empty buffer signaling end-of-stream send it downstream */
433     if ( in->size == 0 )
434     {
435         decodeVideo( pv, in->data, in->size, pts, dts );
436         hb_list_add( pv->list, in );
437         *buf_out = link_buf_list( pv );
438         hb_log( "%s done: %d frames", pv->context->codec->name, pv->nframes );
439         return HB_WORK_DONE;
440     }
441
442     if( in->start >= 0 )
443     {
444         pts = in->start;
445         dts = in->renderOffset;
446     }
447     if ( in->new_chap )
448     {
449         pv->new_chap = in->new_chap;
450         pv->chap_time = pts >= 0? pts : pv->pts_next;
451     }
452     decodeVideo( pv, in->data, in->size, pts, dts );
453     hb_buffer_close( &in );
454     *buf_out = link_buf_list( pv );
455     return HB_WORK_OK;
456 }
457
458 static int decavcodecvInfo( hb_work_object_t *w, hb_work_info_t *info )
459 {
460     hb_work_private_t *pv = w->private_data;
461
462     memset( info, 0, sizeof(*info) );
463
464     if ( pv && pv->context )
465     {
466         AVCodecContext *context = pv->context;
467         info->bitrate = context->bit_rate;
468         info->width = context->width;
469         info->height = context->height;
470
471         /* ffmpeg gives the frame rate in frames per second while HB wants
472          * it in units of the 27MHz MPEG clock. */
473         info->rate = 27000000;
474         info->rate_base = (int64_t)context->time_base.num * 27000000LL /
475                           context->time_base.den;
476         
477         /* Sometimes there's no pixel aspect set in the source. In that case,
478            assume a 1:1 PAR. Otherwise, preserve the source PAR.             */
479         info->pixel_aspect_width = context->sample_aspect_ratio.num ?
480                                         context->sample_aspect_ratio.num : 1;
481         info->pixel_aspect_height = context->sample_aspect_ratio.den ?
482                                         context->sample_aspect_ratio.den : 1;
483
484         /* ffmpeg returns the Pixel Aspect Ratio (PAR). Handbrake wants the
485          * Display Aspect Ratio so we convert by scaling by the Storage
486          * Aspect Ratio (w/h). We do the calc in floating point to get the
487          * rounding right. We round in the second decimal digit because we
488          * scale the (integer) aspect by 9 to preserve the 1st digit.  */
489         info->aspect = ( (double)info->pixel_aspect_width * 
490                          (double)context->width /
491                          (double)info->pixel_aspect_height /
492                          (double)context->height + 0.05 ) * HB_ASPECT_BASE;
493
494         info->profile = context->profile;
495         info->level = context->level;
496         info->name = context->codec->name;
497         return 1;
498     }
499     return 0;
500 }
501
502 static int decavcodecvBSInfo( hb_work_object_t *w, const hb_buffer_t *buf,
503                              hb_work_info_t *info )
504 {
505     return 0;
506 }
507
508 hb_work_object_t hb_decavcodecv =
509 {
510     WORK_DECAVCODECV,
511     "Video decoder (libavcodec)",
512     decavcodecvInit,
513     decavcodecvWork,
514     decavcodecClose,
515     decavcodecvInfo,
516     decavcodecvBSInfo
517 };
518
519
520 // This is a special decoder for ffmpeg streams. The ffmpeg stream reader
521 // includes a parser and passes information from the parser to the decoder
522 // via a codec context kept in the AVStream of the reader's AVFormatContext.
523 // We *have* to use that codec context to decode the stream or we'll get
524 // garbage. ffmpeg_title_scan put a cookie that can be used to get to that
525 // codec context in our codec_param.
526
527 // this routine gets the appropriate context pointer from the ffmpeg
528 // stream reader. it can't be called until we get the first buffer because
529 // we can't guarantee that reader will be called before the our init
530 // routine and if our init is called first we'll get a pointer to the
531 // old scan stream (which has already been closed).
532 static void init_ffmpeg_context( hb_work_object_t *w )
533 {
534     hb_work_private_t *pv = w->private_data;
535     pv->context = hb_ffmpeg_context( w->codec_param );
536
537     // during scan the decoder gets closed & reopened which will
538     // close the codec so reopen it if it's not there
539     if ( ! pv->context->codec )
540     {
541         AVCodec *codec = avcodec_find_decoder( pv->context->codec_id );
542         avcodec_open( pv->context, codec );
543     }
544     // set up our best guess at the frame duration.
545     // the frame rate in the codec seems to be bogus but it's ok in the stream.
546     AVStream *st = hb_ffmpeg_avstream( w->codec_param );
547     AVRational tb = st->time_base;
548     if ( st->r_frame_rate.den && st->r_frame_rate.num )
549     {
550         tb.num = st->r_frame_rate.den;
551         tb.den = st->r_frame_rate.num;
552     }
553     pv->duration = 90000. * tb.num / tb.den;
554
555     // we have to wrap ffmpeg's get_buffer to be able to set the pts (?!)
556     pv->context->opaque = pv;
557     pv->context->get_buffer = get_frame_buf;
558 }
559
560 static void prepare_ffmpeg_buffer( hb_buffer_t * in )
561 {
562     // ffmpeg requires an extra 8 bytes of zero at the end of the buffer and
563     // will seg fault in odd, data dependent ways if it's not there. (my guess
564     // is this is a case of a local performance optimization creating a global
565     // performance degradation since all the time wasted by extraneous data
566     // copies & memory zeroing has to be huge compared to the minor reduction
567     // in inner-loop instructions this affords - modern cpus bottleneck on
568     // memory bandwidth not instruction bandwidth).
569     if ( in->size + FF_INPUT_BUFFER_PADDING_SIZE > in->alloc )
570     {
571         // have to realloc to add the padding
572         hb_buffer_realloc( in, in->size + FF_INPUT_BUFFER_PADDING_SIZE );
573     }
574     memset( in->data + in->size, 0, FF_INPUT_BUFFER_PADDING_SIZE );
575 }
576
577 static int decavcodecviInit( hb_work_object_t * w, hb_job_t * job )
578 {
579
580     hb_work_private_t *pv = calloc( 1, sizeof( hb_work_private_t ) );
581     w->private_data = pv;
582     pv->job   = job;
583     pv->list = hb_list_init();
584
585     return 0;
586 }
587
588 static int decavcodecviWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
589                              hb_buffer_t ** buf_out )
590 {
591     hb_work_private_t *pv = w->private_data;
592     if ( ! pv->context )
593     {
594         init_ffmpeg_context( w );
595
596         switch ( pv->context->codec_id )
597         {
598             // These are the only formats whose timestamps we'll believe.
599             // All others are treated as CFR (i.e., we take the first timestamp
600             // then generate all the others from the frame rate). The reason for
601             // this is that the M$ encoders are so frigging buggy with garbage
602             // like packed b-frames (vfw divx mpeg4) that believing their timestamps
603             // results in discarding more than half the video frames because they'll
604             // be out of sequence (and attempting to reseqence them doesn't work
605             // because it's the timestamps that are wrong, not the decoded frame
606             // order). All hail Redmond, ancestral home of the rich & stupid.
607             case CODEC_ID_MPEG2VIDEO:
608             case CODEC_ID_RAWVIDEO:
609             case CODEC_ID_H264:
610             case CODEC_ID_VC1:
611                 break;
612
613             default:
614                 pv->ignore_pts = 1;
615                 break;
616         }
617     }
618     hb_buffer_t *in = *buf_in;
619     int64_t pts = -1;
620
621     *buf_in = NULL;
622
623     /* if we got an empty buffer signaling end-of-stream send it downstream */
624     if ( in->size == 0 )
625     {
626         /* flush any frames left in the decoder */
627         while ( decodeFrame( pv, NULL, 0 ) )
628         {
629         }
630         hb_list_add( pv->list, in );
631         *buf_out = link_buf_list( pv );
632         hb_log( "%s done: %d frames %d drops", pv->context->codec->name,
633                 pv->nframes, pv->ndrops );
634         return HB_WORK_DONE;
635     }
636
637     if( in->start >= 0 )
638     {
639         // use the first timestamp as our 'next expected' pts
640         if ( pv->pts_next <= 0 )
641         {
642             pv->pts_next = in->start;
643         }
644
645         if ( ! pv->ignore_pts )
646         {
647             pts = in->start;
648             if ( pv->pts > 0 )
649             {
650                 hb_log( "overwriting pts %lld with %lld (diff %d)",
651                         pv->pts, pts, pts - pv->pts );
652             }
653             if ( pv->pts_next - pts >= pv->duration )
654             {
655                 // this frame starts more than a frame time before where
656                 // the nominal frame rate says it should - drop it.
657                 // log the first 10 drops so we'll know what's going on.
658                 if ( pv->ndrops++ < 10 )
659                 {
660                     hb_log( "time reversal next %.0f pts %lld (diff %g)",
661                             pv->pts_next, pts, pv->pts_next - pts );
662                 }
663                 hb_buffer_close( &in );
664                 return HB_WORK_OK;
665             }
666             pv->pts = pts;
667         }
668     }
669
670     if ( in->new_chap )
671     {
672         pv->new_chap = in->new_chap;
673         pv->chap_time = pts >= 0? pts : pv->pts_next;
674     }
675     prepare_ffmpeg_buffer( in );
676     decodeFrame( pv, in->data, in->size );
677     hb_buffer_close( &in );
678     *buf_out = link_buf_list( pv );
679     return HB_WORK_OK;
680 }
681
682 static int decavcodecviInfo( hb_work_object_t *w, hb_work_info_t *info )
683 {
684     if ( decavcodecvInfo( w, info ) )
685     {
686         // the frame rate in the codec seems to be bogus but it's ok in the stream.
687         AVStream *st = hb_ffmpeg_avstream( w->codec_param );
688         AVRational tb;
689         if ( st->r_frame_rate.den && st->r_frame_rate.num )
690         {
691             tb.num = st->r_frame_rate.den;
692             tb.den = st->r_frame_rate.num;
693         }
694         else
695         {
696             tb = st->time_base;
697         }
698
699         // ffmpeg gives the frame rate in frames per second while HB wants
700         // it in units of the 27MHz MPEG clock. */
701         info->rate = 27000000;
702         info->rate_base = (int64_t)tb.num * 27000000LL / tb.den;
703         return 1;
704     }
705     return 0;
706 }
707
708 static void decodeAudio( hb_work_private_t *pv, uint8_t *data, int size )
709 {
710     AVCodecContext *context = pv->context;
711     int pos = 0;
712
713     while ( pos < size )
714     {
715         int16_t buffer[AVCODEC_MAX_AUDIO_FRAME_SIZE];
716         int out_size = sizeof(buffer);
717         int len = avcodec_decode_audio2( context, buffer, &out_size,
718                                          data + pos, size - pos );
719         if ( len <= 0 )
720         {
721             return;
722         }
723         pos += len;
724         if( out_size > 0 )
725         {
726             hb_buffer_t *buf = hb_buffer_init( 2 * out_size );
727
728             double pts = pv->pts_next;
729             buf->start = pts;
730             out_size >>= 1;
731             pts += out_size * pv->duration;
732             buf->stop  = pts;
733             pv->pts_next = pts;
734
735             float *fl32 = (float *)buf->data;
736             int i;
737             for( i = 0; i < out_size; ++i )
738             {
739                 fl32[i] = buffer[i];
740             }
741             hb_list_add( pv->list, buf );
742         }
743     }
744 }
745
746 static int decavcodecaiWork( hb_work_object_t *w, hb_buffer_t **buf_in,
747                     hb_buffer_t **buf_out )
748 {
749     hb_work_private_t *pv = w->private_data;
750     if ( ! pv->context )
751     {
752         init_ffmpeg_context( w );
753         pv->duration = 90000. /
754                     (double)( pv->context->sample_rate * pv->context->channels );
755     }
756     hb_buffer_t *in = *buf_in;
757
758     if ( in->start >= 0 &&
759          ( pv->pts_next < 0 || ( in->start - pv->pts_next ) > 90*100 ) )
760     {
761         pv->pts_next = in->start;
762     }
763     prepare_ffmpeg_buffer( in );
764     decodeAudio( pv, in->data, in->size );
765     *buf_out = link_buf_list( pv );
766
767     return HB_WORK_OK;
768 }
769
770 hb_work_object_t hb_decavcodecvi =
771 {
772     WORK_DECAVCODECVI,
773     "Video decoder (ffmpeg streams)",
774     decavcodecviInit,
775     decavcodecviWork,
776     decavcodecClose,
777     decavcodecviInfo,
778     decavcodecvBSInfo
779 };
780
781 hb_work_object_t hb_decavcodecai =
782 {
783     WORK_DECAVCODECAI,
784     "Audio decoder (ffmpeg streams)",
785     decavcodecviInit,
786     decavcodecaiWork,
787     decavcodecClose,
788     decavcodecInfo,
789     decavcodecBSInfo
790 };