OSDN Git Service

- change aspect from a scaled int to a double so we can handle the wider
[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
64 #include "libavcodec/avcodec.h"
65 #include "libavformat/avformat.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 struct hb_work_private_s
85 {
86     hb_job_t             *job;
87     AVCodecContext       *context;
88     AVCodecParserContext *parser;
89     hb_list_t            *list;
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)
93     int                  new_chap;
94     int                  ignore_pts; // workaround M$ bugs
95     int                  nframes;
96     int                  ndrops;
97     double               duration;  // frame duration (for video)
98 };
99
100
101
102 /***********************************************************************
103  * hb_work_decavcodec_init
104  ***********************************************************************
105  *
106  **********************************************************************/
107 static int decavcodecInit( hb_work_object_t * w, hb_job_t * job )
108 {
109     AVCodec * codec;
110
111     hb_work_private_t * pv = calloc( 1, sizeof( hb_work_private_t ) );
112     w->private_data = pv;
113
114     pv->job   = job;
115
116     int codec_id = w->codec_param;
117     /*XXX*/
118     if ( codec_id == 0 )
119         codec_id = CODEC_ID_MP2;
120     codec = avcodec_find_decoder( codec_id );
121     pv->parser = av_parser_init( codec_id );
122
123     pv->context = avcodec_alloc_context();
124     avcodec_open( pv->context, codec );
125
126     return 0;
127 }
128
129 /***********************************************************************
130  * Close
131  ***********************************************************************
132  *
133  **********************************************************************/
134 static void decavcodecClose( hb_work_object_t * w )
135 {
136     hb_work_private_t * pv = w->private_data;
137     if ( pv->parser )
138         {
139                 av_parser_close(pv->parser);
140         }
141     if ( pv->context && pv->context->codec )
142     {
143         avcodec_close( pv->context );
144     }
145     if ( pv->list )
146     {
147         hb_list_close( &pv->list );
148     }
149 }
150
151 /***********************************************************************
152  * Work
153  ***********************************************************************
154  *
155  **********************************************************************/
156 static int decavcodecWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
157                     hb_buffer_t ** buf_out )
158 {
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];
163     uint64_t cur;
164     unsigned char *parser_output_buffer;
165     int parser_output_buffer_len;
166
167     if ( (*buf_in)->size <= 0 )
168     {
169         /* EOF on input stream - send it downstream & say that we're done */
170         *buf_out = *buf_in;
171         *buf_in = NULL;
172         return HB_WORK_DONE;
173     }
174
175     *buf_out = NULL;
176
177     cur = ( in->start < 0 )? pv->pts_next : in->start;
178
179     pos = 0;
180     while( pos < in->size )
181     {
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 );
185         out_size = 0;
186         uncompressed_len = 0;
187         if (parser_output_buffer_len)
188         {
189             out_size = sizeof(buffer);
190             uncompressed_len = avcodec_decode_audio2( pv->context, buffer,
191                                                       &out_size,
192                                                       parser_output_buffer,
193                                                       parser_output_buffer_len );
194         }
195         if( out_size )
196         {
197             short * s16;
198             float * fl32;
199
200             buf = hb_buffer_init( 2 * out_size );
201
202             int sample_size_in_bytes = 2;   // Default to 2 bytes
203             switch (pv->context->sample_fmt)
204             {
205               case SAMPLE_FMT_S16:
206                 sample_size_in_bytes = 2;
207                 break;
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 */
210               default:
211                 hb_log("decavcodecWork - Unknown Sample Format from avcodec_decode_audio (%d) !", pv->context->sample_fmt);
212                 break;
213             }
214
215             buf->start = cur;
216             buf->stop  = cur + 90000 * ( out_size / (sample_size_in_bytes * pv->context->channels) ) /
217                          pv->context->sample_rate;
218             cur = buf->stop;
219
220             s16  = buffer;
221             fl32 = (float *) buf->data;
222             for( i = 0; i < out_size / 2; i++ )
223             {
224                 fl32[i] = s16[i];
225             }
226
227             if( last )
228             {
229                 last = last->next = buf;
230             }
231             else
232             {
233                 *buf_out = last = buf;
234             }
235         }
236
237         pos += len;
238     }
239
240     pv->pts_next = cur;
241
242     return HB_WORK_OK;
243 }
244
245 static int decavcodecInfo( hb_work_object_t *w, hb_work_info_t *info )
246 {
247     hb_work_private_t *pv = w->private_data;
248
249     memset( info, 0, sizeof(*info) );
250
251     if ( pv && pv->context )
252     {
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;
259         return 1;
260     }
261     return 0;
262 }
263
264 static int decavcodecBSInfo( hb_work_object_t *w, const hb_buffer_t *buf,
265                              hb_work_info_t *info )
266 {
267     hb_work_private_t *pv = w->private_data;
268
269     memset( info, 0, sizeof(*info) );
270
271     if ( pv && pv->context )
272     {
273         return decavcodecInfo( w, info );
274     }
275     // XXX
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 :
279                                                            CODEC_ID_MP2 );
280     if ( codec )
281     {
282         static char codec_name[64];
283
284         info->name =  strncpy( codec_name, codec->name, sizeof(codec_name)-1 );
285         info->bitrate = 384000;
286         info->rate = 48000;
287         info->rate_base = 1;
288         info->channel_layout = HB_INPUT_CH_LAYOUT_STEREO;
289         return 1;
290     }
291     return -1;
292 }
293
294 /* -------------------------------------------------------------
295  * General purpose video decoder using libavcodec
296  */
297
298 static uint8_t *copy_plane( uint8_t *dst, uint8_t* src, int dstride, int sstride,
299                             int h )
300 {
301     if ( dstride == sstride )
302     {
303         memcpy( dst, src, dstride * h );
304         return dst + dstride * h;
305     }
306     int lbytes = dstride <= sstride? dstride : sstride;
307     while ( --h >= 0 )
308     {
309         memcpy( dst, src, lbytes );
310         src += sstride;
311         dst += dstride;
312     }
313     return dst;
314 }
315
316 /* Note: assumes frame format is PIX_FMT_YUV420P */
317 static hb_buffer_t *copy_frame( AVCodecContext *context, AVFrame *frame )
318 {
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;
322
323     dst = copy_plane( dst, frame->data[0], w, frame->linesize[0], h );
324     w >>= 1; h >>= 1;
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 );
327
328     return buf;
329 }
330
331 static int get_frame_buf( AVCodecContext *context, AVFrame *frame )
332 {
333     hb_work_private_t *pv = context->opaque;
334     frame->pts = pv->pts;
335     pv->pts = -1;
336
337     return avcodec_default_get_buffer( context, frame );
338 }
339
340 static void log_chapter( hb_work_private_t *pv, int chap_num, int64_t pts )
341 {
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 );
345 }
346
347 static int decodeFrame( hb_work_private_t *pv, uint8_t *data, int size )
348 {
349     int got_picture;
350     AVFrame frame;
351
352     avcodec_decode_video( pv->context, &frame, &got_picture, data, size );
353     if( got_picture )
354     {
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;
368         if ( pts < 0 )
369         {
370             pts = pv->pts_next;
371         }
372         if ( pv->duration == 0 )
373         {
374             pv->duration = 90000. * pv->context->time_base.num /
375                            pv->context->time_base.den;
376         }
377         double frame_dur = pv->duration;
378         frame_dur += frame.repeat_pict * frame_dur * 0.5;
379         pv->pts_next = pts + frame_dur;
380
381         hb_buffer_t *buf = copy_frame( pv->context, &frame );
382         buf->start = pts;
383
384         if ( pv->new_chap && buf->start >= pv->chap_time )
385         {
386             buf->new_chap = pv->new_chap;
387             pv->new_chap = 0;
388             pv->chap_time = 0;
389             if ( pv->job )
390             {
391                 log_chapter( pv, buf->new_chap, buf->start );
392             }
393         }
394         else if ( pv->job && pv->nframes == 0 )
395         {
396             log_chapter( pv, pv->job->chapter_start, buf->start );
397         }
398         hb_list_add( pv->list, buf );
399         ++pv->nframes;
400     }
401     return got_picture;
402 }
403
404 static void decodeVideo( hb_work_private_t *pv, uint8_t *data, int size,
405                          int64_t pts, int64_t dts )
406 {
407     /*
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).
412      */
413     int pos = 0;
414     do {
415         uint8_t *pout;
416         int pout_len;
417         int len = av_parser_parse( pv->parser, pv->context, &pout, &pout_len,
418                                    data + pos, size - pos, pts, dts );
419         pos += len;
420
421         if ( pout_len > 0 )
422         {
423             pv->pts = pv->parser->pts;
424             decodeFrame( pv, pout, pout_len );
425         }
426     } while ( pos < size );
427
428     /* the stuff above flushed the parser, now flush the decoder */
429     while ( size == 0 && decodeFrame( pv, NULL, 0 ) )
430     {
431     }
432 }
433
434 static hb_buffer_t *link_buf_list( hb_work_private_t *pv )
435 {
436     hb_buffer_t *head = hb_list_item( pv->list, 0 );
437
438     if ( head )
439     {
440         hb_list_rem( pv->list, head );
441
442         hb_buffer_t *last = head, *buf;
443
444         while ( ( buf = hb_list_item( pv->list, 0 ) ) != NULL )
445         {
446             hb_list_rem( pv->list, buf );
447             last->next = buf;
448             last = buf;
449         }
450     }
451     return head;
452 }
453
454
455 static int decavcodecvInit( hb_work_object_t * w, hb_job_t * job )
456 {
457
458     hb_work_private_t *pv = calloc( 1, sizeof( hb_work_private_t ) );
459     w->private_data = pv;
460     pv->job   = job;
461     pv->list = hb_list_init();
462
463     int codec_id = w->codec_param;
464     pv->parser = av_parser_init( codec_id );
465     pv->context = avcodec_alloc_context2( CODEC_TYPE_VIDEO );
466
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;
470
471     AVCodec *codec = avcodec_find_decoder( codec_id );
472
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 );
481
482     return 0;
483 }
484
485 static int decavcodecvWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
486                             hb_buffer_t ** buf_out )
487 {
488     hb_work_private_t *pv = w->private_data;
489     hb_buffer_t *in = *buf_in;
490     int64_t pts = -1;
491     int64_t dts = pts;
492
493     *buf_in = NULL;
494
495     /* if we got an empty buffer signaling end-of-stream send it downstream */
496     if ( in->size == 0 )
497     {
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 );
502         return HB_WORK_DONE;
503     }
504
505     if( in->start >= 0 )
506     {
507         pts = in->start;
508         dts = in->renderOffset;
509     }
510     if ( in->new_chap )
511     {
512         pv->new_chap = in->new_chap;
513         pv->chap_time = pts >= 0? pts : pv->pts_next;
514     }
515     decodeVideo( pv, in->data, in->size, pts, dts );
516     hb_buffer_close( &in );
517     *buf_out = link_buf_list( pv );
518     return HB_WORK_OK;
519 }
520
521 static int decavcodecvInfo( hb_work_object_t *w, hb_work_info_t *info )
522 {
523     hb_work_private_t *pv = w->private_data;
524
525     memset( info, 0, sizeof(*info) );
526
527     if ( pv && pv->context )
528     {
529         AVCodecContext *context = pv->context;
530         info->bitrate = context->bit_rate;
531         info->width = context->width;
532         info->height = context->height;
533
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;
539         
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;
546
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
550          * rounding right. */
551         info->aspect = (double)info->pixel_aspect_width * 
552                        (double)context->width /
553                        (double)info->pixel_aspect_height /
554                        (double)context->height;
555
556         info->profile = context->profile;
557         info->level = context->level;
558         info->name = context->codec->name;
559         return 1;
560     }
561     return 0;
562 }
563
564 static int decavcodecvBSInfo( hb_work_object_t *w, const hb_buffer_t *buf,
565                              hb_work_info_t *info )
566 {
567     return 0;
568 }
569
570 hb_work_object_t hb_decavcodecv =
571 {
572     WORK_DECAVCODECV,
573     "Video decoder (libavcodec)",
574     decavcodecvInit,
575     decavcodecvWork,
576     decavcodecClose,
577     decavcodecvInfo,
578     decavcodecvBSInfo
579 };
580
581
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.
588
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 )
595 {
596     hb_work_private_t *pv = w->private_data;
597     pv->context = hb_ffmpeg_context( w->codec_param );
598
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 )
602     {
603         AVCodec *codec = avcodec_find_decoder( pv->context->codec_id );
604         avcodec_open( pv->context, codec );
605     }
606     // set up our best guess at the frame duration.
607     // the frame rate in the codec is usually bogus but it's sometimes
608     // ok in the stream.
609     AVStream *st = hb_ffmpeg_avstream( w->codec_param );
610     AVRational tb;
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 )
615     {
616         tb = st->time_base;
617     }
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 )
620     {
621         tb = st->codec->time_base;
622     }
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 )
625     {
626         tb.num = st->r_frame_rate.den;
627         tb.den = st->r_frame_rate.num;
628     }
629     else
630     {
631         tb.num = 1001;  /*XXX*/
632         tb.den = 30000; /*XXX*/
633     }
634     pv->duration = 90000. * tb.num / tb.den;
635
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;
639 }
640
641 static void prepare_ffmpeg_buffer( hb_buffer_t * in )
642 {
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 )
651     {
652         // have to realloc to add the padding
653         hb_buffer_realloc( in, in->size + FF_INPUT_BUFFER_PADDING_SIZE );
654     }
655     memset( in->data + in->size, 0, FF_INPUT_BUFFER_PADDING_SIZE );
656 }
657
658 static int decavcodecviInit( hb_work_object_t * w, hb_job_t * job )
659 {
660
661     hb_work_private_t *pv = calloc( 1, sizeof( hb_work_private_t ) );
662     w->private_data = pv;
663     pv->job   = job;
664     pv->list = hb_list_init();
665
666     return 0;
667 }
668
669 static int decavcodecviWork( hb_work_object_t * w, hb_buffer_t ** buf_in,
670                              hb_buffer_t ** buf_out )
671 {
672     hb_work_private_t *pv = w->private_data;
673     if ( ! pv->context )
674     {
675         init_ffmpeg_context( w );
676
677         switch ( pv->context->codec_id )
678         {
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:
690             case CODEC_ID_H264:
691             case CODEC_ID_VC1:
692                 break;
693
694             default:
695                 pv->ignore_pts = 1;
696                 break;
697         }
698     }
699     hb_buffer_t *in = *buf_in;
700     int64_t pts = -1;
701
702     *buf_in = NULL;
703
704     /* if we got an empty buffer signaling end-of-stream send it downstream */
705     if ( in->size == 0 )
706     {
707         /* flush any frames left in the decoder */
708         while ( decodeFrame( pv, NULL, 0 ) )
709         {
710         }
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 );
715         return HB_WORK_DONE;
716     }
717
718     if( in->start >= 0 )
719     {
720         // use the first timestamp as our 'next expected' pts
721         if ( pv->pts_next <= 0 )
722         {
723             pv->pts_next = in->start;
724         }
725
726         if ( ! pv->ignore_pts )
727         {
728             pts = in->start;
729             if ( pv->pts > 0 )
730             {
731                 hb_log( "overwriting pts %lld with %lld (diff %d)",
732                         pv->pts, pts, pts - pv->pts );
733             }
734             if ( pv->pts_next - pts >= pv->duration )
735             {
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 )
740                 {
741                     hb_log( "time reversal next %.0f pts %lld (diff %g)",
742                             pv->pts_next, pts, pv->pts_next - pts );
743                 }
744                 hb_buffer_close( &in );
745                 return HB_WORK_OK;
746             }
747             pv->pts = pts;
748         }
749     }
750
751     if ( in->new_chap )
752     {
753         pv->new_chap = in->new_chap;
754         pv->chap_time = pts >= 0? pts : pv->pts_next;
755     }
756     prepare_ffmpeg_buffer( in );
757     decodeFrame( pv, in->data, in->size );
758     hb_buffer_close( &in );
759     *buf_out = link_buf_list( pv );
760     return HB_WORK_OK;
761 }
762
763 static int decavcodecviInfo( hb_work_object_t *w, hb_work_info_t *info )
764 {
765     if ( decavcodecvInfo( w, info ) )
766     {
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 );
777         AVRational tb;
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 )
782         {
783             tb = st->time_base;
784         }
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 )
787         {
788             tb = st->codec->time_base;
789         }
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 )
792         {
793             tb.num = st->r_frame_rate.den;
794             tb.den = st->r_frame_rate.num;
795         }
796         else
797         {
798             tb.num = 1001;  /*XXX*/
799             tb.den = 30000; /*XXX*/
800         }
801
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;
806         return 1;
807     }
808     return 0;
809 }
810
811 static void decodeAudio( hb_work_private_t *pv, uint8_t *data, int size )
812 {
813     AVCodecContext *context = pv->context;
814     int pos = 0;
815
816     while ( pos < size )
817     {
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 );
822         if ( len <= 0 )
823         {
824             return;
825         }
826         pos += len;
827         if( out_size > 0 )
828         {
829             hb_buffer_t *buf = hb_buffer_init( 2 * out_size );
830
831             double pts = pv->pts_next;
832             buf->start = pts;
833             out_size >>= 1;
834             pts += out_size * pv->duration;
835             buf->stop  = pts;
836             pv->pts_next = pts;
837
838             float *fl32 = (float *)buf->data;
839             int i;
840             for( i = 0; i < out_size; ++i )
841             {
842                 fl32[i] = buffer[i];
843             }
844             hb_list_add( pv->list, buf );
845         }
846     }
847 }
848
849 static int decavcodecaiWork( hb_work_object_t *w, hb_buffer_t **buf_in,
850                     hb_buffer_t **buf_out )
851 {
852     if ( (*buf_in)->size <= 0 )
853     {
854         /* EOF on input stream - send it downstream & say that we're done */
855         *buf_out = *buf_in;
856         *buf_in = NULL;
857         return HB_WORK_DONE;
858     }
859
860     hb_work_private_t *pv = w->private_data;
861     if ( ! pv->context )
862     {
863         init_ffmpeg_context( w );
864         pv->duration = 90000. /
865                     (double)( pv->context->sample_rate * pv->context->channels );
866     }
867     hb_buffer_t *in = *buf_in;
868
869     if ( in->start >= 0 &&
870          ( pv->pts_next < 0 || ( in->start - pv->pts_next ) > 90*100 ) )
871     {
872         pv->pts_next = in->start;
873     }
874     prepare_ffmpeg_buffer( in );
875     decodeAudio( pv, in->data, in->size );
876     *buf_out = link_buf_list( pv );
877
878     return HB_WORK_OK;
879 }
880
881 hb_work_object_t hb_decavcodecvi =
882 {
883     WORK_DECAVCODECVI,
884     "Video decoder (ffmpeg streams)",
885     decavcodecviInit,
886     decavcodecviWork,
887     decavcodecClose,
888     decavcodecviInfo,
889     decavcodecvBSInfo
890 };
891
892 hb_work_object_t hb_decavcodecai =
893 {
894     WORK_DECAVCODECAI,
895     "Audio decoder (ffmpeg streams)",
896     decavcodecviInit,
897     decavcodecaiWork,
898     decavcodecClose,
899     decavcodecInfo,
900     decavcodecBSInfo
901 };