mirror of https://git.ffmpeg.org/ffmpeg.git
Fix pts handling when encoding with libdirac.
patch by Anuradha Suraparaju, anuradha rd.bbc.co uk Originally committed as revision 14191 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
2a72e494c3
commit
f73b204000
|
@ -55,6 +55,12 @@ typedef struct FfmpegDiracEncoderParams
|
||||||
/** input frame buffer */
|
/** input frame buffer */
|
||||||
unsigned char *p_in_frame_buf;
|
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 */
|
/** queue storing encoded frames */
|
||||||
FfmpegDiracSchroQueue enc_frame_queue;
|
FfmpegDiracSchroQueue enc_frame_queue;
|
||||||
|
|
||||||
|
@ -236,6 +242,7 @@ static int libdirac_encode_frame(AVCodecContext *avccontext,
|
||||||
FfmpegDiracSchroEncodedFrame* p_frame_output = NULL;
|
FfmpegDiracSchroEncodedFrame* p_frame_output = NULL;
|
||||||
FfmpegDiracSchroEncodedFrame* p_next_output_frame = NULL;
|
FfmpegDiracSchroEncodedFrame* p_next_output_frame = NULL;
|
||||||
int go = 1;
|
int go = 1;
|
||||||
|
int last_frame_in_sequence = 0;
|
||||||
|
|
||||||
if (data == NULL) {
|
if (data == NULL) {
|
||||||
/* push end of sequence if not already signalled */
|
/* push end of sequence if not already signalled */
|
||||||
|
@ -278,18 +285,39 @@ static int libdirac_encode_frame(AVCodecContext *avccontext,
|
||||||
case ENC_STATE_AVAIL:
|
case ENC_STATE_AVAIL:
|
||||||
case ENC_STATE_EOS:
|
case ENC_STATE_EOS:
|
||||||
assert (p_dirac_params->p_encoder->enc_buf.size > 0);
|
assert (p_dirac_params->p_encoder->enc_buf.size > 0);
|
||||||
/* 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,
|
/* 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.buffer,
|
||||||
p_dirac_params->p_encoder->enc_buf.size);
|
p_dirac_params->p_encoder->enc_buf.size);
|
||||||
|
|
||||||
p_frame_output->size = 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->size = p_dirac_params->enc_buf_size;
|
||||||
|
p_frame_output->p_encbuf = p_dirac_params->enc_buf;
|
||||||
p_frame_output->frame_num =
|
p_frame_output->frame_num =
|
||||||
p_dirac_params->p_encoder->enc_pparams.pnum;
|
p_dirac_params->p_encoder->enc_pparams.pnum;
|
||||||
|
|
||||||
|
@ -300,10 +328,8 @@ static int libdirac_encode_frame(AVCodecContext *avccontext,
|
||||||
ff_dirac_schro_queue_push_back (&p_dirac_params->enc_frame_queue,
|
ff_dirac_schro_queue_push_back (&p_dirac_params->enc_frame_queue,
|
||||||
p_frame_output);
|
p_frame_output);
|
||||||
|
|
||||||
if (state == ENC_STATE_EOS) {
|
p_dirac_params->enc_buf_size = 0;
|
||||||
p_dirac_params->eos_pulled = 1;
|
p_dirac_params->enc_buf = NULL;
|
||||||
go = 0;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ENC_STATE_BUFFER:
|
case ENC_STATE_BUFFER:
|
||||||
|
@ -322,6 +348,11 @@ static int libdirac_encode_frame(AVCodecContext *avccontext,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy 'next' frame in queue */
|
/* 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 =
|
p_next_output_frame =
|
||||||
ff_dirac_schro_queue_pop(&p_dirac_params->enc_frame_queue);
|
ff_dirac_schro_queue_pop(&p_dirac_params->enc_frame_queue);
|
||||||
|
|
||||||
|
@ -336,6 +367,17 @@ static int libdirac_encode_frame(AVCodecContext *avccontext,
|
||||||
avccontext->coded_frame->pts = p_next_output_frame->frame_num;
|
avccontext->coded_frame->pts = p_next_output_frame->frame_num;
|
||||||
enc_size = p_next_output_frame->size;
|
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 */
|
/* free frame */
|
||||||
DiracFreeFrame(p_next_output_frame);
|
DiracFreeFrame(p_next_output_frame);
|
||||||
|
|
||||||
|
@ -353,6 +395,10 @@ static int libdirac_encode_close(AVCodecContext *avccontext)
|
||||||
ff_dirac_schro_queue_free(&p_dirac_params->enc_frame_queue,
|
ff_dirac_schro_queue_free(&p_dirac_params->enc_frame_queue,
|
||||||
DiracFreeFrame);
|
DiracFreeFrame);
|
||||||
|
|
||||||
|
/* free the encoder buffer */
|
||||||
|
if (p_dirac_params->enc_buf_size)
|
||||||
|
av_freep(&p_dirac_params->enc_buf);
|
||||||
|
|
||||||
/* free the input frame buffer */
|
/* free the input frame buffer */
|
||||||
av_freep(&p_dirac_params->p_in_frame_buf);
|
av_freep(&p_dirac_params->p_in_frame_buf);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue