Mercurial > libavcodec.hg
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 ; |
