Mercurial > libavcodec.hg
changeset 7252:e674db16f1c6 libavcodec
Fix pts handling when encoding with libdirac.
patch by Anuradha Suraparaju, anuradha rd.bbc.co uk
author | diego |
---|---|
date | Sat, 12 Jul 2008 20:09:50 +0000 |
parents | 48dd72fdca91 |
children | 2f5b98d0aa13 |
files | libdiracenc.c |
diffstat | 1 files changed, 59 insertions(+), 13 deletions(-) [+] |
line wrap: on
line diff
--- a/libdiracenc.c Sat Jul 12 18:42:00 2008 +0000 +++ b/libdiracenc.c Sat Jul 12 20:09:50 2008 +0000 @@ -55,6 +55,12 @@ /** input frame buffer */ unsigned char *p_in_frame_buf; + /** buffer to store encoder output before writing it to the frame queue */ + unsigned char *enc_buf; + + /** size of encoder buffer */ + int enc_buf_size; + /** queue storing encoded frames */ FfmpegDiracSchroQueue enc_frame_queue; @@ -236,6 +242,7 @@ FfmpegDiracSchroEncodedFrame* p_frame_output = NULL; FfmpegDiracSchroEncodedFrame* p_next_output_frame = NULL; int go = 1; + int last_frame_in_sequence = 0; if (data == NULL) { /* push end of sequence if not already signalled */ @@ -278,18 +285,39 @@ case ENC_STATE_AVAIL: case ENC_STATE_EOS: assert (p_dirac_params->p_encoder->enc_buf.size > 0); + + /* All non-frame data is prepended to actual frame data to + * be able to set the pts correctly. So we don't write data + * to the frame output queue until we actually have a frame + */ + + p_dirac_params->enc_buf = av_realloc ( + p_dirac_params->enc_buf, + p_dirac_params->enc_buf_size + + p_dirac_params->p_encoder->enc_buf.size + ); + memcpy(p_dirac_params->enc_buf + p_dirac_params->enc_buf_size, + p_dirac_params->p_encoder->enc_buf.buffer, + p_dirac_params->p_encoder->enc_buf.size); + + p_dirac_params->enc_buf_size += + p_dirac_params->p_encoder->enc_buf.size; + + if (state == ENC_STATE_EOS) { + p_dirac_params->eos_pulled = 1; + go = 0; + } + + /* If non-frame data, don't output it until it we get an + * encoded frame back from the encoder. */ + if (p_dirac_params->p_encoder->enc_pparams.pnum == -1) + break; + /* create output frame */ p_frame_output = av_mallocz(sizeof(FfmpegDiracSchroEncodedFrame)); /* set output data */ - p_frame_output->p_encbuf = - av_malloc(p_dirac_params->p_encoder->enc_buf.size); - - memcpy(p_frame_output->p_encbuf, - p_dirac_params->p_encoder->enc_buf.buffer, - p_dirac_params->p_encoder->enc_buf.size); - - p_frame_output->size = p_dirac_params->p_encoder->enc_buf.size; - + p_frame_output->size = p_dirac_params->enc_buf_size; + p_frame_output->p_encbuf = p_dirac_params->enc_buf; p_frame_output->frame_num = p_dirac_params->p_encoder->enc_pparams.pnum; @@ -300,10 +328,8 @@ ff_dirac_schro_queue_push_back (&p_dirac_params->enc_frame_queue, p_frame_output); - if (state == ENC_STATE_EOS) { - p_dirac_params->eos_pulled = 1; - go = 0; - } + p_dirac_params->enc_buf_size = 0; + p_dirac_params->enc_buf = NULL; break; case ENC_STATE_BUFFER: @@ -322,6 +348,11 @@ } /* copy 'next' frame in queue */ + + if (p_dirac_params->enc_frame_queue.size == 1 && + p_dirac_params->eos_pulled) + last_frame_in_sequence = 1; + p_next_output_frame = ff_dirac_schro_queue_pop(&p_dirac_params->enc_frame_queue); @@ -336,6 +367,17 @@ avccontext->coded_frame->pts = p_next_output_frame->frame_num; enc_size = p_next_output_frame->size; + /* Append the end of sequence information to the last frame in the + * sequence. */ + if (last_frame_in_sequence && p_dirac_params->enc_buf_size > 0) + { + memcpy (frame + enc_size, p_dirac_params->enc_buf, + p_dirac_params->enc_buf_size); + enc_size += p_dirac_params->enc_buf_size; + av_freep (&p_dirac_params->enc_buf); + p_dirac_params->enc_buf_size = 0; + } + /* free frame */ DiracFreeFrame(p_next_output_frame); @@ -353,6 +395,10 @@ ff_dirac_schro_queue_free(&p_dirac_params->enc_frame_queue, DiracFreeFrame); + /* free the encoder buffer */ + if (p_dirac_params->enc_buf_size) + av_freep(&p_dirac_params->enc_buf); + /* free the input frame buffer */ av_freep(&p_dirac_params->p_in_frame_buf);