diff options
Diffstat (limited to 'libhb/decavcodec.c')
-rw-r--r-- | libhb/decavcodec.c | 132 |
1 files changed, 70 insertions, 62 deletions
diff --git a/libhb/decavcodec.c b/libhb/decavcodec.c index fd58c5c28..1bba19990 100644 --- a/libhb/decavcodec.c +++ b/libhb/decavcodec.c @@ -231,10 +231,10 @@ static int decavcodecaInit( hb_work_object_t * w, hb_job_t * job ) if ( w->audio != NULL ) { - if ( hb_need_downmix( w->audio->config.in.channel_layout, + if ( hb_need_downmix( w->audio->config.in.channel_layout, w->audio->config.out.mixdown) ) { - pv->downmix = hb_downmix_init(w->audio->config.in.channel_layout, + pv->downmix = hb_downmix_init(w->audio->config.in.channel_layout, w->audio->config.out.mixdown); hb_downmix_set_chan_map( pv->downmix, &hb_smpte_chan_map, &hb_smpte_chan_map ); } @@ -328,7 +328,7 @@ static int decavcodecaWork( hb_work_object_t * w, hb_buffer_t ** buf_in, *buf_out = NULL; - if ( in->start < -1 && pv->pts_next <= 0 ) + if ( in->s.start < -1 && pv->pts_next <= 0 ) { // discard buffers that start before video time 0 return HB_WORK_OK; @@ -341,7 +341,7 @@ static int decavcodecaWork( hb_work_object_t * w, hb_buffer_t ** buf_in, int pout_len; int64_t cur; - cur = in->start; + cur = in->s.start; if ( pv->parser != NULL ) { @@ -443,10 +443,10 @@ static int decavcodecaBSInfo( hb_work_object_t *w, const hb_buffer_t *buf, if ( parser != NULL ) { - len = av_parser_parse2( parser, context, &pbuffer, - &pbuffer_size, buf->data + pos, - buf->size - pos, buf->start, - buf->start, 0 ); + len = av_parser_parse2( parser, context, &pbuffer, + &pbuffer_size, buf->data + pos, + buf->size - pos, buf->s.start, + buf->s.start, 0 ); } else { @@ -461,7 +461,7 @@ static int decavcodecaBSInfo( hb_work_object_t *w, const hb_buffer_t *buf, avp.data = pbuffer; avp.size = pbuffer_size; - len = avcodec_decode_audio3( context, (int16_t*)buffer, + len = avcodec_decode_audio3( context, (int16_t*)buffer, &out_size, &avp ); if ( len > 0 && context->sample_rate > 0 ) { @@ -474,13 +474,13 @@ static int decavcodecaBSInfo( hb_work_object_t *w, const hb_buffer_t *buf, info->bitrate = context->bit_rate; info->rate = context->sample_rate; info->rate_base = 1; - info->channel_layout = - hb_ff_layout_xlat(context->channel_layout, + info->channel_layout = + hb_ff_layout_xlat(context->channel_layout, context->channels); ret = 1; if ( context->channels && isamp ) { - info->samples_per_frame = out_size / + info->samples_per_frame = out_size / (isamp * context->channels); } break; @@ -552,7 +552,7 @@ static hb_buffer_t *copy_frame( hb_work_private_t *pv, AVFrame *frame ) { // have to convert to our internal color space and/or rescale AVPicture dstpic; - avpicture_fill( &dstpic, dst, PIX_FMT_YUV420P, w, h ); + hb_avpicture_fill( &dstpic, buf ); if ( ! pv->sws_context || pv->sws_width != context->width || @@ -575,9 +575,14 @@ static hb_buffer_t *copy_frame( hb_work_private_t *pv, AVFrame *frame ) } else { + w = buf->plane[0].stride; + h = buf->plane[0].height; dst = copy_plane( dst, frame->data[0], w, frame->linesize[0], h ); - w = (w + 1) >> 1; h = (h + 1) >> 1; + w = buf->plane[1].stride; + h = buf->plane[1].height; dst = copy_plane( dst, frame->data[1], w, frame->linesize[1], h ); + w = buf->plane[2].stride; + h = buf->plane[2].height; dst = copy_plane( dst, frame->data[2], w, frame->linesize[2], h ); } return buf; @@ -621,7 +626,7 @@ static void flushDelayQueue( hb_work_private_t *pv ) // flush all the video packets left on our timestamp-reordering delay q while ( ( buf = pv->delayq[slot] ) != NULL ) { - buf->start = heap_pop( &pv->pts_heap ); + buf->s.start = heap_pop( &pv->pts_heap ); hb_list_add( pv->list, buf ); pv->delayq[slot] = NULL; slot = ( slot + 1 ) & (HEAP_SIZE-1); @@ -708,15 +713,15 @@ static void checkCadence( int * cadence, uint16_t flags, int64_t start ) } /* - * Decodes a video frame from the specified raw packet data + * Decodes a video frame from the specified raw packet data * ('data', 'size', 'sequence'). * The output of this function is stored in 'pv->list', which contains a list * of zero or more decoded packets. - * - * The returned packets are guaranteed to have their timestamps in the correct - * order, even if the original packets decoded by libavcodec have misordered + * + * The returned packets are guaranteed to have their timestamps in the correct + * order, even if the original packets decoded by libavcodec have misordered * timestamps, due to the use of 'packed B-frames'. - * + * * Internally the set of decoded packets may be buffered in 'pv->delayq' * until enough packets have been decoded so that the timestamps can be * correctly rewritten, if this is necessary. @@ -741,7 +746,7 @@ static int decodeFrame( hb_work_object_t *w, uint8_t *data, int size, int sequen avp.dts = dts; if ( avcodec_decode_video2( pv->context, &frame, &got_picture, &avp ) < 0 ) { - ++pv->decode_errors; + ++pv->decode_errors; } if ( global_verbosity_level <= 1 ) { @@ -770,15 +775,15 @@ static int decodeFrame( hb_work_object_t *w, uint8_t *data, int size, int sequen // ffmpeg makes it hard to attach a pts to a frame. if the MPEG ES // packet had a pts we handed it to av_parser_parse (if the packet had - // no pts we set it to AV_NOPTS_VALUE, but before the parse we can't - // distinguish between the start of a video frame with no pts & an - // intermediate packet of some frame which never has a pts). we hope - // that when parse returns the frame to us the pts we originally - // handed it will be in parser->pts. we put this pts into avp.pts so - // that when avcodec_decode_video finally gets around to allocating an - // AVFrame to hold the decoded frame, avcodec_default_get_buffer can - // stuff that pts into the it. if all of these relays worked at this - // point frame.pts should hold the frame's pts from the original data + // no pts we set it to AV_NOPTS_VALUE, but before the parse we can't + // distinguish between the start of a video frame with no pts & an + // intermediate packet of some frame which never has a pts). we hope + // that when parse returns the frame to us the pts we originally + // handed it will be in parser->pts. we put this pts into avp.pts so + // that when avcodec_decode_video finally gets around to allocating an + // AVFrame to hold the decoded frame, avcodec_default_get_buffer can + // stuff that pts into the it. if all of these relays worked at this + // point frame.pts should hold the frame's pts from the original data // stream or AV_NOPTS_VALUE if it didn't have one. in the latter case // we generate the next pts in sequence for it. if ( !pv->frame_duration_set ) @@ -827,21 +832,23 @@ static int decodeFrame( hb_work_object_t *w, uint8_t *data, int size, int sequen if ( ! pv->job || ! pv->brokenByMicrosoft ) { buf = copy_frame( pv, &frame ); - buf->start = pts; + buf->s.start = pts; buf->sequence = sequence; - buf->flags = flags; - if ( pv->new_chap && buf->start >= pv->chap_time ) + + buf->s.flags = flags; + + if ( pv->new_chap && buf->s.start >= pv->chap_time ) { - buf->new_chap = pv->new_chap; + buf->s.new_chap = pv->new_chap; + log_chapter( pv, pv->new_chap, buf->s.start ); pv->new_chap = 0; pv->chap_time = 0; - log_chapter( pv, buf->new_chap, buf->start ); } else if ( pv->nframes == 0 && pv->job ) { - log_chapter( pv, pv->job->chapter_start, buf->start ); + log_chapter( pv, pv->job->chapter_start, buf->s.start ); } - checkCadence( pv->cadence, buf->flags, buf->start ); + checkCadence( pv->cadence, flags, buf->s.start ); hb_list_add( pv->list, buf ); ++pv->nframes; return got_picture; @@ -873,27 +880,28 @@ static int decodeFrame( hb_work_object_t *w, uint8_t *data, int size, int sequen if ( ( buf = pv->delayq[slot] ) != NULL ) { pv->queue_primed = 1; - buf->start = heap_pop( &pv->pts_heap ); + buf->s.start = heap_pop( &pv->pts_heap ); - if ( pv->new_chap && buf->start >= pv->chap_time ) + if ( pv->new_chap && buf->s.start >= pv->chap_time ) { - buf->new_chap = pv->new_chap; + buf->s.new_chap = pv->new_chap; + log_chapter( pv, pv->new_chap, buf->s.start ); pv->new_chap = 0; pv->chap_time = 0; - log_chapter( pv, buf->new_chap, buf->start ); } else if ( pv->nframes == 0 && pv->job ) { - log_chapter( pv, pv->job->chapter_start, buf->start ); + log_chapter( pv, pv->job->chapter_start, buf->s.start ); } - checkCadence( pv->cadence, buf->flags, buf->start ); + checkCadence( pv->cadence, buf->s.flags, buf->s.start ); hb_list_add( pv->list, buf ); } // add the new frame to the delayq & push its timestamp on the heap buf = copy_frame( pv, &frame ); buf->sequence = sequence; - buf->flags = flags; + /* Store picture flags for later use by filters */ + buf->s.flags = flags; pv->delayq[slot] = buf; heap_push( &pv->pts_heap, pts ); @@ -1085,7 +1093,7 @@ static int setup_extradata( hb_work_object_t *w, hb_buffer_t *in ) hb_work_private_t *pv = w->private_data; // we can't call the avstream funcs but the read_header func in the - // AVInputFormat may set up some state in the AVContext. In particular + // AVInputFormat may set up some state in the AVContext. In particular // vc1t_read_header allocates 'extradata' to deal with header issues // related to Microsoft's bizarre engineering notions. We alloc a chunk // of space to make vc1 work then associate the codec with the context. @@ -1096,7 +1104,7 @@ static int setup_extradata( hb_work_object_t *w, hb_buffer_t *in ) pv->context->extradata_size = 0; // av_malloc uses posix_memalign which is allowed to // return NULL when allocating 0 bytes. We use extradata == NULL - // to trigger initialization of extradata and the decoder, so + // to trigger initialization of extradata and the decoder, so // we can not set it to NULL here. So allocate a small // buffer instead. pv->context->extradata = av_malloc(1); @@ -1193,14 +1201,14 @@ static int decavcodecvWork( hb_work_object_t * w, hb_buffer_t ** buf_in, pv->video_codec_opened = 1; } - if( in->start >= 0 ) + if( in->s.start >= 0 ) { - pts = in->start; - dts = in->renderOffset; + pts = in->s.start; + dts = in->s.renderOffset; } - if ( in->new_chap ) + if ( in->s.new_chap ) { - pv->new_chap = in->new_chap; + pv->new_chap = in->s.new_chap; pv->chap_time = pts >= 0? pts : pv->pts_next; } decodeVideo( w, in->data, in->size, in->sequence, pts, dts ); @@ -1262,7 +1270,7 @@ static void compute_frame_duration( hb_work_private_t *pv ) pv->context->time_base.num * max_fps > pv->context->time_base.den && pv->context->time_base.den > pv->context->time_base.num * 8L ) { - duration = (double)pv->context->time_base.num / + duration = (double)pv->context->time_base.num / (double)pv->context->time_base.den; if ( pv->context->ticks_per_frame > 1 ) { @@ -1277,7 +1285,7 @@ static void compute_frame_duration( hb_work_private_t *pv ) if ( pv->context->time_base.num * max_fps > pv->context->time_base.den && pv->context->time_base.den > pv->context->time_base.num * 8L ) { - duration = (double)pv->context->time_base.num / + duration = (double)pv->context->time_base.num / (double)pv->context->time_base.den; if ( pv->context->ticks_per_frame > 1 ) { @@ -1376,10 +1384,10 @@ hb_work_object_t hb_decavcodecv = .bsinfo = decavcodecvBSInfo }; -static hb_buffer_t * downmixAudio( - hb_audio_t *audio, - hb_work_private_t *pv, - hb_sample_t *buffer, +static hb_buffer_t * downmixAudio( + hb_audio_t *audio, + hb_work_private_t *pv, + hb_sample_t *buffer, int channels, int nsamples ) { @@ -1459,8 +1467,8 @@ static void decodeAudio( hb_audio_t * audio, hb_work_private_t *pv, uint8_t *dat buf = hb_buffer_init( avp.size ); memcpy( buf->data, avp.data, avp.size ); - buf->start = pv->pts_next; - buf->stop = pts_next; + buf->s.start = pv->pts_next; + buf->s.stop = pts_next; hb_list_add( pv->list, buf ); pv->pts_next = pts_next; continue; @@ -1486,7 +1494,7 @@ static void decodeAudio( hb_audio_t * audio, hb_work_private_t *pv, uint8_t *dat // get output buffer size then malloc a buffer buffer = av_malloc( nsamples * sizeof(hb_sample_t) ); - // we're doing straight sample format conversion which + // we're doing straight sample format conversion which // behaves as if there were only one channel. const void * const ibuf[6] = { pv->buffer }; void * const obuf[6] = { buffer }; @@ -1499,8 +1507,8 @@ static void decodeAudio( hb_audio_t * audio, hb_work_private_t *pv, uint8_t *dat hb_buffer_t * buf; buf = downmixAudio( audio, pv, buffer, context->channels, nsamples ); - buf->start = pv->pts_next; - buf->stop = pts_next; + buf->s.start = pv->pts_next; + buf->s.stop = pts_next; hb_list_add( pv->list, buf ); pv->pts_next = pts_next; |