Originally committed as revision 14191 to svn://svn.ffmpeg.org/ffmpeg/trunk
Anuradha Suraparaju authored on 2008/07/13 05:09:50... | ... |
@@ -55,6 +55,12 @@ typedef struct FfmpegDiracEncoderParams |
55 | 55 |
/** input frame buffer */ |
56 | 56 |
unsigned char *p_in_frame_buf; |
57 | 57 |
|
58 |
+ /** buffer to store encoder output before writing it to the frame queue */ |
|
59 |
+ unsigned char *enc_buf; |
|
60 |
+ |
|
61 |
+ /** size of encoder buffer */ |
|
62 |
+ int enc_buf_size; |
|
63 |
+ |
|
58 | 64 |
/** queue storing encoded frames */ |
59 | 65 |
FfmpegDiracSchroQueue enc_frame_queue; |
60 | 66 |
|
... | ... |
@@ -236,6 +242,7 @@ static int libdirac_encode_frame(AVCodecContext *avccontext, |
236 | 236 |
FfmpegDiracSchroEncodedFrame* p_frame_output = NULL; |
237 | 237 |
FfmpegDiracSchroEncodedFrame* p_next_output_frame = NULL; |
238 | 238 |
int go = 1; |
239 |
+ int last_frame_in_sequence = 0; |
|
239 | 240 |
|
240 | 241 |
if (data == NULL) { |
241 | 242 |
/* push end of sequence if not already signalled */ |
... | ... |
@@ -278,18 +285,39 @@ static int libdirac_encode_frame(AVCodecContext *avccontext, |
278 | 278 |
case ENC_STATE_AVAIL: |
279 | 279 |
case ENC_STATE_EOS: |
280 | 280 |
assert (p_dirac_params->p_encoder->enc_buf.size > 0); |
281 |
- /* create output frame */ |
|
282 |
- p_frame_output = av_mallocz(sizeof(FfmpegDiracSchroEncodedFrame)); |
|
283 |
- /* set output data */ |
|
284 |
- p_frame_output->p_encbuf = |
|
285 |
- av_malloc(p_dirac_params->p_encoder->enc_buf.size); |
|
286 | 281 |
|
287 |
- memcpy(p_frame_output->p_encbuf, |
|
282 |
+ /* All non-frame data is prepended to actual frame data to |
|
283 |
+ * be able to set the pts correctly. So we don't write data |
|
284 |
+ * to the frame output queue until we actually have a frame |
|
285 |
+ */ |
|
286 |
+ |
|
287 |
+ p_dirac_params->enc_buf = av_realloc ( |
|
288 |
+ p_dirac_params->enc_buf, |
|
289 |
+ p_dirac_params->enc_buf_size + |
|
290 |
+ p_dirac_params->p_encoder->enc_buf.size |
|
291 |
+ ); |
|
292 |
+ memcpy(p_dirac_params->enc_buf + p_dirac_params->enc_buf_size, |
|
288 | 293 |
p_dirac_params->p_encoder->enc_buf.buffer, |
289 | 294 |
p_dirac_params->p_encoder->enc_buf.size); |
290 | 295 |
|
291 |
- p_frame_output->size = p_dirac_params->p_encoder->enc_buf.size; |
|
296 |
+ p_dirac_params->enc_buf_size += |
|
297 |
+ p_dirac_params->p_encoder->enc_buf.size; |
|
298 |
+ |
|
299 |
+ if (state == ENC_STATE_EOS) { |
|
300 |
+ p_dirac_params->eos_pulled = 1; |
|
301 |
+ go = 0; |
|
302 |
+ } |
|
303 |
+ |
|
304 |
+ /* If non-frame data, don't output it until it we get an |
|
305 |
+ * encoded frame back from the encoder. */ |
|
306 |
+ if (p_dirac_params->p_encoder->enc_pparams.pnum == -1) |
|
307 |
+ break; |
|
292 | 308 |
|
309 |
+ /* create output frame */ |
|
310 |
+ p_frame_output = av_mallocz(sizeof(FfmpegDiracSchroEncodedFrame)); |
|
311 |
+ /* set output data */ |
|
312 |
+ p_frame_output->size = p_dirac_params->enc_buf_size; |
|
313 |
+ p_frame_output->p_encbuf = p_dirac_params->enc_buf; |
|
293 | 314 |
p_frame_output->frame_num = |
294 | 315 |
p_dirac_params->p_encoder->enc_pparams.pnum; |
295 | 316 |
|
... | ... |
@@ -300,10 +328,8 @@ static int libdirac_encode_frame(AVCodecContext *avccontext, |
300 | 300 |
ff_dirac_schro_queue_push_back (&p_dirac_params->enc_frame_queue, |
301 | 301 |
p_frame_output); |
302 | 302 |
|
303 |
- if (state == ENC_STATE_EOS) { |
|
304 |
- p_dirac_params->eos_pulled = 1; |
|
305 |
- go = 0; |
|
306 |
- } |
|
303 |
+ p_dirac_params->enc_buf_size = 0; |
|
304 |
+ p_dirac_params->enc_buf = NULL; |
|
307 | 305 |
break; |
308 | 306 |
|
309 | 307 |
case ENC_STATE_BUFFER: |
... | ... |
@@ -322,6 +348,11 @@ static int libdirac_encode_frame(AVCodecContext *avccontext, |
322 | 322 |
} |
323 | 323 |
|
324 | 324 |
/* copy 'next' frame in queue */ |
325 |
+ |
|
326 |
+ if (p_dirac_params->enc_frame_queue.size == 1 && |
|
327 |
+ p_dirac_params->eos_pulled) |
|
328 |
+ last_frame_in_sequence = 1; |
|
329 |
+ |
|
325 | 330 |
p_next_output_frame = |
326 | 331 |
ff_dirac_schro_queue_pop(&p_dirac_params->enc_frame_queue); |
327 | 332 |
|
... | ... |
@@ -336,6 +367,17 @@ static int libdirac_encode_frame(AVCodecContext *avccontext, |
336 | 336 |
avccontext->coded_frame->pts = p_next_output_frame->frame_num; |
337 | 337 |
enc_size = p_next_output_frame->size; |
338 | 338 |
|
339 |
+ /* Append the end of sequence information to the last frame in the |
|
340 |
+ * sequence. */ |
|
341 |
+ if (last_frame_in_sequence && p_dirac_params->enc_buf_size > 0) |
|
342 |
+ { |
|
343 |
+ memcpy (frame + enc_size, p_dirac_params->enc_buf, |
|
344 |
+ p_dirac_params->enc_buf_size); |
|
345 |
+ enc_size += p_dirac_params->enc_buf_size; |
|
346 |
+ av_freep (&p_dirac_params->enc_buf); |
|
347 |
+ p_dirac_params->enc_buf_size = 0; |
|
348 |
+ } |
|
349 |
+ |
|
339 | 350 |
/* free frame */ |
340 | 351 |
DiracFreeFrame(p_next_output_frame); |
341 | 352 |
|
... | ... |
@@ -353,6 +395,10 @@ static int libdirac_encode_close(AVCodecContext *avccontext) |
353 | 353 |
ff_dirac_schro_queue_free(&p_dirac_params->enc_frame_queue, |
354 | 354 |
DiracFreeFrame); |
355 | 355 |
|
356 |
+ /* free the encoder buffer */ |
|
357 |
+ if (p_dirac_params->enc_buf_size) |
|
358 |
+ av_freep(&p_dirac_params->enc_buf); |
|
359 |
+ |
|
356 | 360 |
/* free the input frame buffer */ |
357 | 361 |
av_freep(&p_dirac_params->p_in_frame_buf); |
358 | 362 |
|