Mercurial > libavcodec.hg
comparison libschroedingerenc.c @ 7253:2f5b98d0aa13 libavcodec
Fix pts handling when encoding with libschroedinger, closes issue 453.
patch by Anuradha Suraparaju, anuradha rd.bbc.co uk
| author | diego |
|---|---|
| date | Sat, 12 Jul 2008 20:12:18 +0000 |
| parents | e943e1409077 |
| children | e6348a5656e0 |
comparison
equal
deleted
inserted
replaced
| 7252:e674db16f1c6 | 7253:2f5b98d0aa13 |
|---|---|
| 55 int frame_size; | 55 int frame_size; |
| 56 | 56 |
| 57 /** Schroedinger encoder handle*/ | 57 /** Schroedinger encoder handle*/ |
| 58 SchroEncoder* encoder; | 58 SchroEncoder* encoder; |
| 59 | 59 |
| 60 /** buffer to store encoder output before writing it to the frame queue*/ | |
| 61 unsigned char *enc_buf; | |
| 62 | |
| 63 /** Size of encoder buffer*/ | |
| 64 int enc_buf_size; | |
| 65 | |
| 60 /** queue storing encoded frames */ | 66 /** queue storing encoded frames */ |
| 61 FfmpegDiracSchroQueue enc_frame_queue; | 67 FfmpegDiracSchroQueue enc_frame_queue; |
| 62 | 68 |
| 63 /** end of sequence signalled */ | 69 /** end of sequence signalled */ |
| 64 int eos_signalled; | 70 int eos_signalled; |
| 253 struct FfmpegDiracSchroEncodedFrame* p_frame_output = NULL; | 259 struct FfmpegDiracSchroEncodedFrame* p_frame_output = NULL; |
| 254 int go = 1; | 260 int go = 1; |
| 255 SchroBuffer *enc_buf; | 261 SchroBuffer *enc_buf; |
| 256 int presentation_frame; | 262 int presentation_frame; |
| 257 int parse_code; | 263 int parse_code; |
| 264 int last_frame_in_sequence = 0; | |
| 258 | 265 |
| 259 if(data == NULL) { | 266 if(data == NULL) { |
| 260 /* Push end of sequence if not already signalled. */ | 267 /* Push end of sequence if not already signalled. */ |
| 261 if (!p_schro_params->eos_signalled) { | 268 if (!p_schro_params->eos_signalled) { |
| 262 schro_encoder_end_of_stream(encoder); | 269 schro_encoder_end_of_stream(encoder); |
| 283 case SCHRO_STATE_END_OF_STREAM: | 290 case SCHRO_STATE_END_OF_STREAM: |
| 284 enc_buf = schro_encoder_pull (encoder, | 291 enc_buf = schro_encoder_pull (encoder, |
| 285 &presentation_frame); | 292 &presentation_frame); |
| 286 assert (enc_buf->length > 0); | 293 assert (enc_buf->length > 0); |
| 287 assert (enc_buf->length <= buf_size); | 294 assert (enc_buf->length <= buf_size); |
| 295 parse_code = enc_buf->data[4]; | |
| 296 | |
| 297 /* All non-frame data is prepended to actual frame data to | |
| 298 * be able to set the pts correctly. So we don't write data | |
| 299 * to the frame output queue until we actually have a frame | |
| 300 */ | |
| 301 p_schro_params->enc_buf = av_realloc ( | |
| 302 p_schro_params->enc_buf, | |
| 303 p_schro_params->enc_buf_size + enc_buf->length | |
| 304 ); | |
| 305 | |
| 306 memcpy(p_schro_params->enc_buf+p_schro_params->enc_buf_size, | |
| 307 enc_buf->data, enc_buf->length); | |
| 308 p_schro_params->enc_buf_size += enc_buf->length; | |
| 309 | |
| 310 | |
| 311 if (state == SCHRO_STATE_END_OF_STREAM) { | |
| 312 p_schro_params->eos_pulled = 1; | |
| 313 go = 0; | |
| 314 } | |
| 315 | |
| 316 if (!SCHRO_PARSE_CODE_IS_PICTURE(parse_code)) { | |
| 317 schro_buffer_unref (enc_buf); | |
| 318 break; | |
| 319 } | |
| 288 | 320 |
| 289 /* Create output frame. */ | 321 /* Create output frame. */ |
| 290 p_frame_output = av_mallocz(sizeof(FfmpegDiracSchroEncodedFrame)); | 322 p_frame_output = av_mallocz(sizeof(FfmpegDiracSchroEncodedFrame)); |
| 291 /* Set output data. */ | 323 /* Set output data. */ |
| 292 p_frame_output->size = enc_buf->length; | 324 p_frame_output->size = p_schro_params->enc_buf_size; |
| 293 p_frame_output->p_encbuf = av_malloc(enc_buf->length); | 325 p_frame_output->p_encbuf = p_schro_params->enc_buf; |
| 294 memcpy(p_frame_output->p_encbuf, enc_buf->data, enc_buf->length); | |
| 295 | |
| 296 parse_code = enc_buf->data[4]; | |
| 297 if (SCHRO_PARSE_CODE_IS_INTRA(parse_code) && | 326 if (SCHRO_PARSE_CODE_IS_INTRA(parse_code) && |
| 298 SCHRO_PARSE_CODE_IS_REFERENCE(parse_code)) { | 327 SCHRO_PARSE_CODE_IS_REFERENCE(parse_code)) { |
| 299 p_frame_output->key_frame = 1; | 328 p_frame_output->key_frame = 1; |
| 300 } | 329 } |
| 301 | 330 |
| 302 /* Parse the coded frame number from the bitstream. Bytes 14 | 331 /* Parse the coded frame number from the bitstream. Bytes 14 |
| 303 * through 17 represesent the frame number. */ | 332 * through 17 represesent the frame number. */ |
| 304 if (SCHRO_PARSE_CODE_IS_PICTURE(parse_code)) | |
| 305 { | |
| 306 assert (enc_buf->length >= 17); | |
| 307 p_frame_output->frame_num = (enc_buf->data[13] << 24) + | 333 p_frame_output->frame_num = (enc_buf->data[13] << 24) + |
| 308 (enc_buf->data[14] << 16) + | 334 (enc_buf->data[14] << 16) + |
| 309 (enc_buf->data[15] << 8) + | 335 (enc_buf->data[15] << 8) + |
| 310 enc_buf->data[16]; | 336 enc_buf->data[16]; |
| 311 } | |
| 312 | 337 |
| 313 ff_dirac_schro_queue_push_back (&p_schro_params->enc_frame_queue, | 338 ff_dirac_schro_queue_push_back (&p_schro_params->enc_frame_queue, |
| 314 p_frame_output); | 339 p_frame_output); |
| 340 p_schro_params->enc_buf_size = 0; | |
| 341 p_schro_params->enc_buf = NULL; | |
| 342 | |
| 315 schro_buffer_unref (enc_buf); | 343 schro_buffer_unref (enc_buf); |
| 316 | 344 |
| 317 if (state == SCHRO_STATE_END_OF_STREAM) { | |
| 318 p_schro_params->eos_pulled = 1; | |
| 319 go = 0; | |
| 320 } | |
| 321 break; | 345 break; |
| 322 | 346 |
| 323 case SCHRO_STATE_NEED_FRAME: | 347 case SCHRO_STATE_NEED_FRAME: |
| 324 go = 0; | 348 go = 0; |
| 325 break; | 349 break; |
| 332 return -1; | 356 return -1; |
| 333 } | 357 } |
| 334 } | 358 } |
| 335 | 359 |
| 336 /* Copy 'next' frame in queue. */ | 360 /* Copy 'next' frame in queue. */ |
| 361 | |
| 362 if (p_schro_params->enc_frame_queue.size == 1 && | |
| 363 p_schro_params->eos_pulled) | |
| 364 last_frame_in_sequence = 1; | |
| 365 | |
| 337 p_frame_output = | 366 p_frame_output = |
| 338 ff_dirac_schro_queue_pop (&p_schro_params->enc_frame_queue); | 367 ff_dirac_schro_queue_pop (&p_schro_params->enc_frame_queue); |
| 339 | 368 |
| 340 if (p_frame_output == NULL) | 369 if (p_frame_output == NULL) |
| 341 return 0; | 370 return 0; |
| 346 * do so since Dirac is a constant frame rate codec. It expects input | 375 * do so since Dirac is a constant frame rate codec. It expects input |
| 347 * to be of constant frame rate. */ | 376 * to be of constant frame rate. */ |
| 348 avccontext->coded_frame->pts = p_frame_output->frame_num; | 377 avccontext->coded_frame->pts = p_frame_output->frame_num; |
| 349 enc_size = p_frame_output->size; | 378 enc_size = p_frame_output->size; |
| 350 | 379 |
| 380 /* Append the end of sequence information to the last frame in the | |
| 381 * sequence. */ | |
| 382 if (last_frame_in_sequence && p_schro_params->enc_buf_size > 0) | |
| 383 { | |
| 384 memcpy (frame + enc_size, p_schro_params->enc_buf, | |
| 385 p_schro_params->enc_buf_size); | |
| 386 enc_size += p_schro_params->enc_buf_size; | |
| 387 av_freep (&p_schro_params->enc_buf); | |
| 388 p_schro_params->enc_buf_size = 0; | |
| 389 } | |
| 390 | |
| 351 /* free frame */ | 391 /* free frame */ |
| 352 SchroedingerFreeFrame (p_frame_output); | 392 SchroedingerFreeFrame (p_frame_output); |
| 353 | 393 |
| 354 return enc_size; | 394 return enc_size; |
| 355 } | 395 } |
| 364 schro_encoder_free(p_schro_params->encoder); | 404 schro_encoder_free(p_schro_params->encoder); |
| 365 | 405 |
| 366 /* Free data in the output frame queue. */ | 406 /* Free data in the output frame queue. */ |
| 367 ff_dirac_schro_queue_free (&p_schro_params->enc_frame_queue, | 407 ff_dirac_schro_queue_free (&p_schro_params->enc_frame_queue, |
| 368 SchroedingerFreeFrame); | 408 SchroedingerFreeFrame); |
| 409 | |
| 410 | |
| 411 /* Free the encoder buffer. */ | |
| 412 if (p_schro_params->enc_buf_size) | |
| 413 av_freep(&p_schro_params->enc_buf); | |
| 369 | 414 |
| 370 /* Free the video format structure. */ | 415 /* Free the video format structure. */ |
| 371 av_freep(&p_schro_params->format); | 416 av_freep(&p_schro_params->format); |
| 372 | 417 |
| 373 return 0 ; | 418 return 0 ; |
