comparison libdiracenc.c @ 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 e943e1409077
children e6348a5656e0
comparison
equal deleted inserted replaced
7251:48dd72fdca91 7252:e674db16f1c6
52 /** Dirac encoder handle */ 52 /** Dirac encoder handle */
53 dirac_encoder_t* p_encoder; 53 dirac_encoder_t* p_encoder;
54 54
55 /** input frame buffer */ 55 /** input frame buffer */
56 unsigned char *p_in_frame_buf; 56 unsigned char *p_in_frame_buf;
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;
57 63
58 /** queue storing encoded frames */ 64 /** queue storing encoded frames */
59 FfmpegDiracSchroQueue enc_frame_queue; 65 FfmpegDiracSchroQueue enc_frame_queue;
60 66
61 /** end of sequence signalled by user, 0 - false, 1 - true */ 67 /** end of sequence signalled by user, 0 - false, 1 - true */
234 dirac_encoder_state_t state; 240 dirac_encoder_state_t state;
235 FfmpegDiracEncoderParams* p_dirac_params = avccontext->priv_data; 241 FfmpegDiracEncoderParams* p_dirac_params = avccontext->priv_data;
236 FfmpegDiracSchroEncodedFrame* p_frame_output = NULL; 242 FfmpegDiracSchroEncodedFrame* p_frame_output = NULL;
237 FfmpegDiracSchroEncodedFrame* p_next_output_frame = NULL; 243 FfmpegDiracSchroEncodedFrame* p_next_output_frame = NULL;
238 int go = 1; 244 int go = 1;
245 int last_frame_in_sequence = 0;
239 246
240 if (data == NULL) { 247 if (data == NULL) {
241 /* push end of sequence if not already signalled */ 248 /* push end of sequence if not already signalled */
242 if (!p_dirac_params->eos_signalled) { 249 if (!p_dirac_params->eos_signalled) {
243 dirac_encoder_end_sequence( p_dirac_params->p_encoder ); 250 dirac_encoder_end_sequence( p_dirac_params->p_encoder );
276 switch (state) 283 switch (state)
277 { 284 {
278 case ENC_STATE_AVAIL: 285 case ENC_STATE_AVAIL:
279 case ENC_STATE_EOS: 286 case ENC_STATE_EOS:
280 assert (p_dirac_params->p_encoder->enc_buf.size > 0); 287 assert (p_dirac_params->p_encoder->enc_buf.size > 0);
281 /* create output frame */ 288
282 p_frame_output = av_mallocz(sizeof(FfmpegDiracSchroEncodedFrame)); 289 /* All non-frame data is prepended to actual frame data to
283 /* set output data */ 290 * be able to set the pts correctly. So we don't write data
284 p_frame_output->p_encbuf = 291 * to the frame output queue until we actually have a frame
285 av_malloc(p_dirac_params->p_encoder->enc_buf.size); 292 */
286 293
287 memcpy(p_frame_output->p_encbuf, 294 p_dirac_params->enc_buf = av_realloc (
295 p_dirac_params->enc_buf,
296 p_dirac_params->enc_buf_size +
297 p_dirac_params->p_encoder->enc_buf.size
298 );
299 memcpy(p_dirac_params->enc_buf + p_dirac_params->enc_buf_size,
288 p_dirac_params->p_encoder->enc_buf.buffer, 300 p_dirac_params->p_encoder->enc_buf.buffer,
289 p_dirac_params->p_encoder->enc_buf.size); 301 p_dirac_params->p_encoder->enc_buf.size);
290 302
291 p_frame_output->size = p_dirac_params->p_encoder->enc_buf.size; 303 p_dirac_params->enc_buf_size +=
292 304 p_dirac_params->p_encoder->enc_buf.size;
293 p_frame_output->frame_num =
294 p_dirac_params->p_encoder->enc_pparams.pnum;
295
296 if (p_dirac_params->p_encoder->enc_pparams.ptype == INTRA_PICTURE &&
297 p_dirac_params->p_encoder->enc_pparams.rtype == REFERENCE_PICTURE)
298 p_frame_output->key_frame = 1;
299
300 ff_dirac_schro_queue_push_back (&p_dirac_params->enc_frame_queue,
301 p_frame_output);
302 305
303 if (state == ENC_STATE_EOS) { 306 if (state == ENC_STATE_EOS) {
304 p_dirac_params->eos_pulled = 1; 307 p_dirac_params->eos_pulled = 1;
305 go = 0; 308 go = 0;
306 } 309 }
310
311 /* If non-frame data, don't output it until it we get an
312 * encoded frame back from the encoder. */
313 if (p_dirac_params->p_encoder->enc_pparams.pnum == -1)
314 break;
315
316 /* create output frame */
317 p_frame_output = av_mallocz(sizeof(FfmpegDiracSchroEncodedFrame));
318 /* set output data */
319 p_frame_output->size = p_dirac_params->enc_buf_size;
320 p_frame_output->p_encbuf = p_dirac_params->enc_buf;
321 p_frame_output->frame_num =
322 p_dirac_params->p_encoder->enc_pparams.pnum;
323
324 if (p_dirac_params->p_encoder->enc_pparams.ptype == INTRA_PICTURE &&
325 p_dirac_params->p_encoder->enc_pparams.rtype == REFERENCE_PICTURE)
326 p_frame_output->key_frame = 1;
327
328 ff_dirac_schro_queue_push_back (&p_dirac_params->enc_frame_queue,
329 p_frame_output);
330
331 p_dirac_params->enc_buf_size = 0;
332 p_dirac_params->enc_buf = NULL;
307 break; 333 break;
308 334
309 case ENC_STATE_BUFFER: 335 case ENC_STATE_BUFFER:
310 go = 0; 336 go = 0;
311 break; 337 break;
320 return -1; 346 return -1;
321 } 347 }
322 } 348 }
323 349
324 /* copy 'next' frame in queue */ 350 /* copy 'next' frame in queue */
351
352 if (p_dirac_params->enc_frame_queue.size == 1 &&
353 p_dirac_params->eos_pulled)
354 last_frame_in_sequence = 1;
355
325 p_next_output_frame = 356 p_next_output_frame =
326 ff_dirac_schro_queue_pop(&p_dirac_params->enc_frame_queue); 357 ff_dirac_schro_queue_pop(&p_dirac_params->enc_frame_queue);
327 358
328 if (p_next_output_frame == NULL) 359 if (p_next_output_frame == NULL)
329 return 0; 360 return 0;
334 * so since Dirac is a constant framerate codec. It expects input to be 365 * so since Dirac is a constant framerate codec. It expects input to be
335 * of constant framerate. */ 366 * of constant framerate. */
336 avccontext->coded_frame->pts = p_next_output_frame->frame_num; 367 avccontext->coded_frame->pts = p_next_output_frame->frame_num;
337 enc_size = p_next_output_frame->size; 368 enc_size = p_next_output_frame->size;
338 369
370 /* Append the end of sequence information to the last frame in the
371 * sequence. */
372 if (last_frame_in_sequence && p_dirac_params->enc_buf_size > 0)
373 {
374 memcpy (frame + enc_size, p_dirac_params->enc_buf,
375 p_dirac_params->enc_buf_size);
376 enc_size += p_dirac_params->enc_buf_size;
377 av_freep (&p_dirac_params->enc_buf);
378 p_dirac_params->enc_buf_size = 0;
379 }
380
339 /* free frame */ 381 /* free frame */
340 DiracFreeFrame(p_next_output_frame); 382 DiracFreeFrame(p_next_output_frame);
341 383
342 return enc_size; 384 return enc_size;
343 } 385 }
350 dirac_encoder_close(p_dirac_params->p_encoder ); 392 dirac_encoder_close(p_dirac_params->p_encoder );
351 393
352 /* free data in the output frame queue */ 394 /* free data in the output frame queue */
353 ff_dirac_schro_queue_free(&p_dirac_params->enc_frame_queue, 395 ff_dirac_schro_queue_free(&p_dirac_params->enc_frame_queue,
354 DiracFreeFrame); 396 DiracFreeFrame);
397
398 /* free the encoder buffer */
399 if (p_dirac_params->enc_buf_size)
400 av_freep(&p_dirac_params->enc_buf);
355 401
356 /* free the input frame buffer */ 402 /* free the input frame buffer */
357 av_freep(&p_dirac_params->p_in_frame_buf); 403 av_freep(&p_dirac_params->p_in_frame_buf);
358 404
359 return 0 ; 405 return 0 ;