OSDN Git Service

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