1 /* 2 * Copyright (C) 2001 Carlos Hasan 3 * Copyright (C) 2001 François Revol 4 * Copyright (C) 2001 Axel Dörfler 5 * Copyright (C) 2004 Marcus Overhagen 6 * Copyright (C) 2009 Stephan Amßus <superstippi@gmx.de> 7 * Copyright (C) 2014 Colin Günther <coling@gmx.de> 8 * 9 * All rights reserved. Distributed under the terms of the MIT License. 10 */ 11 12 //! libavcodec based decoder for Haiku 13 14 #include "AVCodecDecoder.h" 15 16 #include <new> 17 18 #include <assert.h> 19 #include <string.h> 20 21 #include <Bitmap.h> 22 #include <Debug.h> 23 24 25 #undef TRACE 26 //#define TRACE_AV_CODEC 27 #ifdef TRACE_AV_CODEC 28 # define TRACE(x...) printf(x) 29 # define TRACE_AUDIO(x...) printf(x) 30 # define TRACE_VIDEO(x...) printf(x) 31 #else 32 # define TRACE(x...) 33 # define TRACE_AUDIO(x...) 34 # define TRACE_VIDEO(x...) 35 #endif 36 37 //#define LOG_STREAM_TO_FILE 38 #ifdef LOG_STREAM_TO_FILE 39 # include <File.h> 40 static BFile sStreamLogFile("/boot/home/Desktop/AVCodecDebugStream.raw", 41 B_CREATE_FILE | B_ERASE_FILE | B_WRITE_ONLY); 42 static int sDumpedPackets = 0; 43 #endif 44 45 #ifdef __x86_64 46 #define USE_SWS_FOR_COLOR_SPACE_CONVERSION 1 47 #else 48 #define USE_SWS_FOR_COLOR_SPACE_CONVERSION 0 49 // NOTE: David's color space conversion is much faster than the FFmpeg 50 // version. Perhaps the SWS code can be used for unsupported conversions? 51 // Otherwise the alternative code could simply be removed from this file. 52 #endif 53 54 55 struct wave_format_ex { 56 uint16 format_tag; 57 uint16 channels; 58 uint32 frames_per_sec; 59 uint32 avg_bytes_per_sec; 60 uint16 block_align; 61 uint16 bits_per_sample; 62 uint16 extra_size; 63 // extra_data[extra_size] 64 } _PACKED; 65 66 67 // profiling related globals 68 #define DO_PROFILING 0 69 70 static bigtime_t decodingTime = 0; 71 static bigtime_t conversionTime = 0; 72 static long profileCounter = 0; 73 74 75 AVCodecDecoder::AVCodecDecoder() 76 : 77 fHeader(), 78 fInputFormat(), 79 fOutputVideoFormat(), 80 fFrame(0), 81 fIsAudio(false), 82 fCodec(NULL), 83 fContext(avcodec_alloc_context3(NULL)), 84 fDecodedData(NULL), 85 fDecodedDataSizeInBytes(0), 86 fPostProcessedDecodedPicture(avcodec_alloc_frame()), 87 fRawDecodedPicture(avcodec_alloc_frame()), 88 89 fCodecInitDone(false), 90 91 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION 92 fSwsContext(NULL), 93 #else 94 fFormatConversionFunc(NULL), 95 #endif 96 97 fExtraData(NULL), 98 fExtraDataSize(0), 99 fBlockAlign(0), 100 101 fStartTime(0), 102 fOutputFrameCount(0), 103 fOutputFrameRate(1.0), 104 fOutputFrameSize(0), 105 106 fChunkBuffer(NULL), 107 fChunkBufferOffset(0), 108 fChunkBufferSize(0), 109 fAudioDecodeError(false), 110 111 fOutputFrame(avcodec_alloc_frame()), 112 fOutputBufferOffset(0), 113 fOutputBufferSize(0) 114 { 115 TRACE("AVCodecDecoder::AVCodecDecoder()\n"); 116 117 system_info info; 118 get_system_info(&info); 119 120 fContext->err_recognition = AV_EF_CAREFUL; 121 fContext->error_concealment = 3; 122 fContext->thread_count = info.cpu_count; 123 } 124 125 126 AVCodecDecoder::~AVCodecDecoder() 127 { 128 TRACE("[%c] AVCodecDecoder::~AVCodecDecoder()\n", fIsAudio?('a'):('v')); 129 130 #ifdef DO_PROFILING 131 if (profileCounter > 0) { 132 printf("[%c] profile: d1 = %lld, d2 = %lld (%Ld)\n", 133 fIsAudio?('a'):('v'), decodingTime / profileCounter, 134 conversionTime / profileCounter, fFrame); 135 } 136 #endif 137 138 if (fCodecInitDone) 139 avcodec_close(fContext); 140 141 free(fDecodedData); 142 143 av_free(fPostProcessedDecodedPicture); 144 av_free(fRawDecodedPicture); 145 av_free(fContext); 146 av_free(fOutputFrame); 147 148 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION 149 if (fSwsContext != NULL) 150 sws_freeContext(fSwsContext); 151 #endif 152 153 delete[] fExtraData; 154 } 155 156 157 void 158 AVCodecDecoder::GetCodecInfo(media_codec_info* mci) 159 { 160 snprintf(mci->short_name, 32, "%s", fCodec->name); 161 snprintf(mci->pretty_name, 96, "%s", fCodec->long_name); 162 mci->id = 0; 163 mci->sub_id = fCodec->id; 164 } 165 166 167 status_t 168 AVCodecDecoder::Setup(media_format* ioEncodedFormat, const void* infoBuffer, 169 size_t infoSize) 170 { 171 if (ioEncodedFormat->type != B_MEDIA_ENCODED_AUDIO 172 && ioEncodedFormat->type != B_MEDIA_ENCODED_VIDEO) 173 return B_ERROR; 174 175 fIsAudio = (ioEncodedFormat->type == B_MEDIA_ENCODED_AUDIO); 176 TRACE("[%c] AVCodecDecoder::Setup()\n", fIsAudio?('a'):('v')); 177 178 #ifdef TRACE_AV_CODEC 179 char buffer[1024]; 180 string_for_format(*ioEncodedFormat, buffer, sizeof(buffer)); 181 TRACE("[%c] input_format = %s\n", fIsAudio?('a'):('v'), buffer); 182 TRACE("[%c] infoSize = %ld\n", fIsAudio?('a'):('v'), infoSize); 183 TRACE("[%c] user_data_type = %08lx\n", fIsAudio?('a'):('v'), 184 ioEncodedFormat->user_data_type); 185 TRACE("[%c] meta_data_size = %ld\n", fIsAudio?('a'):('v'), 186 ioEncodedFormat->MetaDataSize()); 187 #endif 188 189 media_format_description description; 190 if (BMediaFormats().GetCodeFor(*ioEncodedFormat, 191 B_MISC_FORMAT_FAMILY, &description) == B_OK) { 192 if (description.u.misc.file_format != 'ffmp') 193 return B_NOT_SUPPORTED; 194 fCodec = avcodec_find_decoder(static_cast<CodecID>( 195 description.u.misc.codec)); 196 if (fCodec == NULL) { 197 TRACE(" unable to find the correct FFmpeg " 198 "decoder (id = %lu)\n", description.u.misc.codec); 199 return B_ERROR; 200 } 201 TRACE(" found decoder %s\n", fCodec->name); 202 203 const void* extraData = infoBuffer; 204 fExtraDataSize = infoSize; 205 if (description.family == B_WAV_FORMAT_FAMILY 206 && infoSize >= sizeof(wave_format_ex)) { 207 TRACE(" trying to use wave_format_ex\n"); 208 // Special case extra data in B_WAV_FORMAT_FAMILY 209 const wave_format_ex* waveFormatData 210 = (const wave_format_ex*)infoBuffer; 211 212 size_t waveFormatSize = infoSize; 213 if (waveFormatData != NULL && waveFormatSize > 0) { 214 fBlockAlign = waveFormatData->block_align; 215 TRACE(" found block align: %d\n", fBlockAlign); 216 fExtraDataSize = waveFormatData->extra_size; 217 // skip the wave_format_ex from the extra data. 218 extraData = waveFormatData + 1; 219 } 220 } else { 221 if (fIsAudio) { 222 fBlockAlign 223 = ioEncodedFormat->u.encoded_audio.output 224 .buffer_size; 225 TRACE(" using buffer_size as block align: %d\n", 226 fBlockAlign); 227 } 228 } 229 if (extraData != NULL && fExtraDataSize > 0) { 230 TRACE("AVCodecDecoder: extra data size %ld\n", infoSize); 231 delete[] fExtraData; 232 fExtraData = new(std::nothrow) char[fExtraDataSize]; 233 if (fExtraData != NULL) 234 memcpy(fExtraData, infoBuffer, fExtraDataSize); 235 else 236 fExtraDataSize = 0; 237 } 238 239 fInputFormat = *ioEncodedFormat; 240 return B_OK; 241 } else { 242 TRACE("AVCodecDecoder: BMediaFormats().GetCodeFor() failed.\n"); 243 } 244 245 printf("AVCodecDecoder::Setup failed!\n"); 246 return B_ERROR; 247 } 248 249 250 status_t 251 AVCodecDecoder::SeekedTo(int64 frame, bigtime_t time) 252 { 253 status_t ret = B_OK; 254 // Reset the FFmpeg codec to flush buffers, so we keep the sync 255 if (fCodecInitDone) { 256 avcodec_flush_buffers(fContext); 257 _ResetTempPacket(); 258 } 259 260 // Flush internal buffers as well. 261 fChunkBuffer = NULL; 262 fChunkBufferOffset = 0; 263 fChunkBufferSize = 0; 264 fOutputBufferOffset = 0; 265 fOutputBufferSize = 0; 266 fDecodedDataSizeInBytes = 0; 267 268 fFrame = frame; 269 fStartTime = time; 270 271 return ret; 272 } 273 274 275 status_t 276 AVCodecDecoder::NegotiateOutputFormat(media_format* inOutFormat) 277 { 278 TRACE("AVCodecDecoder::NegotiateOutputFormat() [%c] \n", 279 fIsAudio?('a'):('v')); 280 281 #ifdef TRACE_AV_CODEC 282 char buffer[1024]; 283 string_for_format(*inOutFormat, buffer, sizeof(buffer)); 284 TRACE(" [%c] requested format = %s\n", fIsAudio?('a'):('v'), buffer); 285 #endif 286 287 if (fIsAudio) 288 return _NegotiateAudioOutputFormat(inOutFormat); 289 else 290 return _NegotiateVideoOutputFormat(inOutFormat); 291 } 292 293 294 status_t 295 AVCodecDecoder::Decode(void* outBuffer, int64* outFrameCount, 296 media_header* mediaHeader, media_decode_info* info) 297 { 298 if (!fCodecInitDone) 299 return B_NO_INIT; 300 301 // TRACE("[%c] AVCodecDecoder::Decode() for time %Ld\n", fIsAudio?('a'):('v'), 302 // fStartTime); 303 304 mediaHeader->start_time = fStartTime; 305 306 status_t ret; 307 if (fIsAudio) 308 ret = _DecodeAudio(outBuffer, outFrameCount, mediaHeader, info); 309 else 310 ret = _DecodeVideo(outBuffer, outFrameCount, mediaHeader, info); 311 312 return ret; 313 } 314 315 316 // #pragma mark - 317 318 319 void 320 AVCodecDecoder::_ResetTempPacket() 321 { 322 av_init_packet(&fTempPacket); 323 fTempPacket.size = 0; 324 fTempPacket.data = NULL; 325 } 326 327 328 status_t 329 AVCodecDecoder::_NegotiateAudioOutputFormat(media_format* inOutFormat) 330 { 331 TRACE("AVCodecDecoder::_NegotiateAudioOutputFormat()\n"); 332 333 media_multi_audio_format outputAudioFormat; 334 outputAudioFormat = media_raw_audio_format::wildcard; 335 outputAudioFormat.byte_order = B_MEDIA_HOST_ENDIAN; 336 outputAudioFormat.frame_rate 337 = fInputFormat.u.encoded_audio.output.frame_rate; 338 outputAudioFormat.channel_count 339 = fInputFormat.u.encoded_audio.output.channel_count; 340 outputAudioFormat.format = fInputFormat.u.encoded_audio.output.format; 341 outputAudioFormat.buffer_size 342 = inOutFormat->u.raw_audio.buffer_size; 343 // Check that format is not still a wild card! 344 if (outputAudioFormat.format == 0) { 345 TRACE(" format still a wild-card, assuming B_AUDIO_SHORT.\n"); 346 outputAudioFormat.format = media_raw_audio_format::B_AUDIO_SHORT; 347 } 348 size_t sampleSize = outputAudioFormat.format 349 & media_raw_audio_format::B_AUDIO_SIZE_MASK; 350 // Check that channel count is not still a wild card! 351 if (outputAudioFormat.channel_count == 0) { 352 TRACE(" channel_count still a wild-card, assuming stereo.\n"); 353 outputAudioFormat.channel_count = 2; 354 } 355 356 if (outputAudioFormat.buffer_size == 0) { 357 outputAudioFormat.buffer_size = 512 358 * sampleSize * outputAudioFormat.channel_count; 359 } 360 inOutFormat->type = B_MEDIA_RAW_AUDIO; 361 inOutFormat->u.raw_audio = outputAudioFormat; 362 363 fContext->bit_rate = (int)fInputFormat.u.encoded_audio.bit_rate; 364 fContext->frame_size = (int)fInputFormat.u.encoded_audio.frame_size; 365 fContext->sample_rate 366 = (int)fInputFormat.u.encoded_audio.output.frame_rate; 367 fContext->channels = outputAudioFormat.channel_count; 368 fContext->block_align = fBlockAlign; 369 fContext->extradata = (uint8_t*)fExtraData; 370 fContext->extradata_size = fExtraDataSize; 371 372 // TODO: This probably needs to go away, there is some misconception 373 // about extra data / info buffer and meta data. See 374 // Reader::GetStreamInfo(). The AVFormatReader puts extradata and 375 // extradata_size into media_format::MetaData(), but used to ignore 376 // the infoBuffer passed to GetStreamInfo(). I think this may be why 377 // the code below was added. 378 if (fInputFormat.MetaDataSize() > 0) { 379 fContext->extradata = (uint8_t*)fInputFormat.MetaData(); 380 fContext->extradata_size = fInputFormat.MetaDataSize(); 381 } 382 383 TRACE(" bit_rate %d, sample_rate %d, channels %d, block_align %d, " 384 "extradata_size %d\n", fContext->bit_rate, fContext->sample_rate, 385 fContext->channels, fContext->block_align, fContext->extradata_size); 386 387 // close any previous instance 388 if (fCodecInitDone) { 389 fCodecInitDone = false; 390 avcodec_close(fContext); 391 } 392 393 // open new 394 int result = avcodec_open2(fContext, fCodec, NULL); 395 fCodecInitDone = (result >= 0); 396 397 fStartTime = 0; 398 fOutputFrameSize = sampleSize * outputAudioFormat.channel_count; 399 fOutputFrameCount = outputAudioFormat.buffer_size / fOutputFrameSize; 400 fOutputFrameRate = outputAudioFormat.frame_rate; 401 402 TRACE(" bit_rate = %d, sample_rate = %d, channels = %d, init = %d, " 403 "output frame size: %d, count: %ld, rate: %.2f\n", 404 fContext->bit_rate, fContext->sample_rate, fContext->channels, 405 result, fOutputFrameSize, fOutputFrameCount, fOutputFrameRate); 406 407 fChunkBuffer = NULL; 408 fChunkBufferOffset = 0; 409 fChunkBufferSize = 0; 410 fAudioDecodeError = false; 411 fOutputBufferOffset = 0; 412 fOutputBufferSize = 0; 413 414 _ResetTempPacket(); 415 416 inOutFormat->require_flags = 0; 417 inOutFormat->deny_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS; 418 419 if (!fCodecInitDone) { 420 TRACE("avcodec_open() failed!\n"); 421 return B_ERROR; 422 } 423 424 return B_OK; 425 } 426 427 428 status_t 429 AVCodecDecoder::_NegotiateVideoOutputFormat(media_format* inOutFormat) 430 { 431 TRACE("AVCodecDecoder::_NegotiateVideoOutputFormat()\n"); 432 433 fOutputVideoFormat = fInputFormat.u.encoded_video.output; 434 435 fContext->width = fOutputVideoFormat.display.line_width; 436 fContext->height = fOutputVideoFormat.display.line_count; 437 // fContext->frame_rate = (int)(fOutputVideoFormat.field_rate 438 // * fContext->frame_rate_base); 439 440 fOutputFrameRate = fOutputVideoFormat.field_rate; 441 442 fContext->extradata = (uint8_t*)fExtraData; 443 fContext->extradata_size = fExtraDataSize; 444 445 bool codecCanHandleIncompleteFrames 446 = (fCodec->capabilities & CODEC_CAP_TRUNCATED) != 0; 447 if (codecCanHandleIncompleteFrames) { 448 // Expect and handle video frames to be splitted across consecutive 449 // data chunks. 450 fContext->flags |= CODEC_FLAG_TRUNCATED; 451 } 452 453 TRACE(" requested video format 0x%x\n", 454 inOutFormat->u.raw_video.display.format); 455 456 // Make MediaPlayer happy (if not in rgb32 screen depth and no overlay, 457 // it will only ask for YCbCr, which DrawBitmap doesn't handle, so the 458 // default colordepth is RGB32). 459 if (inOutFormat->u.raw_video.display.format == B_YCbCr422) 460 fOutputVideoFormat.display.format = B_YCbCr422; 461 else 462 fOutputVideoFormat.display.format = B_RGB32; 463 464 // Search for a pixel-format the codec handles 465 // TODO: We should try this a couple of times until it succeeds, each 466 // time using another pixel-format that is supported by the decoder. 467 // But libavcodec doesn't seem to offer any way to tell the decoder 468 // which format it should use. 469 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION 470 if (fSwsContext != NULL) 471 sws_freeContext(fSwsContext); 472 fSwsContext = NULL; 473 #else 474 fFormatConversionFunc = 0; 475 #endif 476 // Iterate over supported codec formats 477 for (int i = 0; i < 1; i++) { 478 // close any previous instance 479 if (fCodecInitDone) { 480 fCodecInitDone = false; 481 avcodec_close(fContext); 482 } 483 // TODO: Set n-th fContext->pix_fmt here 484 if (avcodec_open2(fContext, fCodec, NULL) >= 0) { 485 fCodecInitDone = true; 486 487 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION 488 fSwsContext = sws_getContext(fContext->width, fContext->height, 489 fContext->pix_fmt, fContext->width, fContext->height, 490 colorspace_to_pixfmt(fOutputVideoFormat.display.format), 491 SWS_FAST_BILINEAR, NULL, NULL, NULL); 492 } 493 #else 494 fFormatConversionFunc = resolve_colorspace( 495 fOutputVideoFormat.display.format, fContext->pix_fmt, 496 fContext->width, fContext->height); 497 } 498 if (fFormatConversionFunc != NULL) 499 break; 500 #endif 501 } 502 503 if (!fCodecInitDone) { 504 TRACE("avcodec_open() failed to init codec!\n"); 505 return B_ERROR; 506 } 507 508 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION 509 if (fSwsContext == NULL) { 510 TRACE("No SWS Scale context or decoder has not set the pixel format " 511 "yet!\n"); 512 } 513 #else 514 if (fFormatConversionFunc == NULL) { 515 TRACE("no pixel format conversion function found or decoder has " 516 "not set the pixel format yet!\n"); 517 } 518 #endif 519 520 if (fOutputVideoFormat.display.format == B_YCbCr422) { 521 fOutputVideoFormat.display.bytes_per_row 522 = 2 * fOutputVideoFormat.display.line_width; 523 } else { 524 fOutputVideoFormat.display.bytes_per_row 525 = 4 * fOutputVideoFormat.display.line_width; 526 } 527 528 inOutFormat->type = B_MEDIA_RAW_VIDEO; 529 inOutFormat->u.raw_video = fOutputVideoFormat; 530 531 inOutFormat->require_flags = 0; 532 inOutFormat->deny_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS; 533 534 _ResetTempPacket(); 535 536 #ifdef TRACE_AV_CODEC 537 char buffer[1024]; 538 string_for_format(*inOutFormat, buffer, sizeof(buffer)); 539 TRACE("[v] outFormat = %s\n", buffer); 540 TRACE(" returned video format 0x%x\n", 541 inOutFormat->u.raw_video.display.format); 542 #endif 543 544 return B_OK; 545 } 546 547 548 status_t 549 AVCodecDecoder::_DecodeAudio(void* _buffer, int64* outFrameCount, 550 media_header* mediaHeader, media_decode_info* info) 551 { 552 TRACE_AUDIO("AVCodecDecoder::_DecodeAudio(audio start_time %.6fs)\n", 553 mediaHeader->start_time / 1000000.0); 554 555 *outFrameCount = 0; 556 557 uint8* buffer = reinterpret_cast<uint8*>(_buffer); 558 while (*outFrameCount < fOutputFrameCount) { 559 // Check conditions which would hint at broken code below. 560 if (fOutputBufferSize < 0) { 561 fprintf(stderr, "Decoding read past the end of the output buffer! " 562 "%ld\n", fOutputBufferSize); 563 fOutputBufferSize = 0; 564 } 565 if (fChunkBufferSize < 0) { 566 fprintf(stderr, "Decoding read past the end of the chunk buffer! " 567 "%ld\n", fChunkBufferSize); 568 fChunkBufferSize = 0; 569 } 570 571 if (fOutputBufferSize > 0) { 572 // We still have decoded audio frames from the last 573 // invokation, which start at fOutputBufferOffset 574 // and are of fOutputBufferSize. Copy those into the buffer, 575 // but not more than it can hold. 576 int32 frames = min_c(fOutputFrameCount - *outFrameCount, 577 fOutputBufferSize / fOutputFrameSize); 578 if (frames == 0) 579 debugger("fOutputBufferSize not multiple of frame size!"); 580 size_t remainingSize = frames * fOutputFrameSize; 581 memcpy(buffer, fOutputFrame->data[0] + fOutputBufferOffset, 582 remainingSize); 583 fOutputBufferOffset += remainingSize; 584 fOutputBufferSize -= remainingSize; 585 buffer += remainingSize; 586 *outFrameCount += frames; 587 fStartTime += (bigtime_t)((1000000LL * frames) / fOutputFrameRate); 588 continue; 589 } 590 if (fChunkBufferSize == 0) { 591 // Time to read the next chunk buffer. We use a separate 592 // media_header, since the chunk header may not belong to 593 // the start of the decoded audio frames we return. For 594 // example we may have used frames from a previous invokation, 595 // or we may have to read several chunks until we fill up the 596 // output buffer. 597 media_header chunkMediaHeader; 598 status_t err = GetNextChunk(&fChunkBuffer, &fChunkBufferSize, 599 &chunkMediaHeader); 600 if (err == B_LAST_BUFFER_ERROR) { 601 TRACE_AUDIO(" Last Chunk with chunk size %ld\n", 602 fChunkBufferSize); 603 fChunkBufferSize = 0; 604 return err; 605 } 606 if (err != B_OK || fChunkBufferSize < 0) { 607 printf("GetNextChunk error %ld\n",fChunkBufferSize); 608 fChunkBufferSize = 0; 609 break; 610 } 611 fChunkBufferOffset = 0; 612 fStartTime = chunkMediaHeader.start_time; 613 } 614 615 fTempPacket.data = (uint8_t*)fChunkBuffer + fChunkBufferOffset; 616 fTempPacket.size = fChunkBufferSize; 617 618 avcodec_get_frame_defaults(fOutputFrame); 619 int gotFrame = 0; 620 int usedBytes = avcodec_decode_audio4(fContext, 621 fOutputFrame, &gotFrame, &fTempPacket); 622 if (usedBytes < 0 && !fAudioDecodeError) { 623 // Report failure if not done already 624 printf("########### audio decode error, " 625 "fChunkBufferSize %ld, fChunkBufferOffset %ld\n", 626 fChunkBufferSize, fChunkBufferOffset); 627 fAudioDecodeError = true; 628 } 629 if (usedBytes <= 0) { 630 // Error or failure to produce decompressed output. 631 // Skip the chunk buffer data entirely. 632 usedBytes = fChunkBufferSize; 633 fOutputBufferSize = 0; 634 // Assume the audio decoded until now is broken. 635 memset(_buffer, 0, buffer - (uint8*)_buffer); 636 } else { 637 // Success 638 fAudioDecodeError = false; 639 if (gotFrame == 1) { 640 fOutputBufferSize = av_samples_get_buffer_size(NULL, 641 fContext->channels, fOutputFrame->nb_samples, 642 fContext->sample_fmt, 1); 643 if (fOutputBufferSize < 0) 644 fOutputBufferSize = 0; 645 } else 646 fOutputBufferSize = 0; 647 } 648 //printf(" chunk size: %d, decoded: %d, used: %d\n", 649 //fTempPacket.size, decodedBytes, usedBytes); 650 651 fChunkBufferOffset += usedBytes; 652 fChunkBufferSize -= usedBytes; 653 fOutputBufferOffset = 0; 654 } 655 fFrame += *outFrameCount; 656 TRACE_AUDIO(" frame count: %lld current: %lld\n", *outFrameCount, fFrame); 657 658 return B_OK; 659 } 660 661 662 /*! \brief Fills the outBuffer with an already decoded video frame. 663 664 Besides the main duty described above, this method also fills out the other 665 output parameters as documented below. 666 667 \param outBuffer Pointer to the output buffer to copy the decoded video 668 frame to. 669 \param outFrameCount Pointer to the output variable to assign the number of 670 copied video frames (usually one video frame). 671 \param mediaHeader Pointer to the output media header that contains the 672 decoded video frame properties. 673 \param info TODO (not used at the moment) 674 675 \returns B_OK Decoding a video frame succeeded. 676 \returns B_LAST_BUFFER_ERROR There are no more video frames available. 677 \returns other error codes 678 */ 679 status_t 680 AVCodecDecoder::_DecodeVideo(void* outBuffer, int64* outFrameCount, 681 media_header* mediaHeader, media_decode_info* info) 682 { 683 status_t videoDecodingStatus 684 = fDecodedDataSizeInBytes > 0 ? B_OK : _DecodeNextVideoFrame(); 685 686 if (videoDecodingStatus != B_OK) 687 return videoDecodingStatus; 688 689 *outFrameCount = 1; 690 *mediaHeader = fHeader; 691 memcpy(outBuffer, fDecodedData, fDecodedDataSizeInBytes); 692 693 fDecodedDataSizeInBytes = 0; 694 695 return B_OK; 696 } 697 698 699 /*! \brief Decode next video frame 700 701 We decode exactly one video frame into fDecodedData. To achieve this goal, 702 we might need to request several chunks of encoded data resulting in a 703 variable execution time of this function. 704 705 The length of the decoded video frame is stored in 706 fDecodedDataSizeInBytes. If this variable is greater than zero, you can 707 assert that there is a valid video frame available in fDecodedData. 708 709 The decoded video frame in fDecodedData has color space conversion and 710 deinterlacing already applied. 711 712 To every decoded video frame there is a media_header populated in 713 fHeader, containing the corresponding video frame properties. 714 715 Normally every decoded video frame has a start_time field populated in the 716 associated fHeader, that determines the presentation time of the frame. 717 This relationship will only hold true, when each data chunk that is 718 provided via GetNextChunk() contains data for exactly one encoded video 719 frame (one complete frame) - not more and not less. 720 721 We can decode data chunks that contain partial video frame data, too. In 722 that case, you cannot trust the value of the start_time field in fHeader. 723 We simply have no logic in place to establish a meaningful relationship 724 between an incomplete frame and the start time it should be presented. 725 Though this might change in the future. 726 727 We can decode data chunks that contain more than one video frame, too. In 728 that case, you cannot trust the value of the start_time field in fHeader. 729 We simply have no logic in place to track the start_time across multiple 730 video frames. So a meaningful relationship between the 2nd, 3rd, ... frame 731 and the start time it should be presented isn't established at the moment. 732 Though this might change in the future. 733 734 \return B_OK, when we successfully decoded one video frame 735 */ 736 status_t 737 AVCodecDecoder::_DecodeNextVideoFrame() 738 { 739 assert(fTempPacket.size >= 0); 740 741 while (true) { 742 media_header chunkMediaHeader; 743 744 if (fTempPacket.size == 0) { 745 // Our packet buffer is empty, so fill it now. 746 status_t getNextChunkStatus = GetNextChunk(&fChunkBuffer, 747 &fChunkBufferSize, &chunkMediaHeader); 748 if (getNextChunkStatus != B_OK) { 749 TRACE("AVCodecDecoder::_DecodeNextVideoFrame(): error from " 750 "GetNextChunk(): %s\n", strerror(err)); 751 return getNextChunkStatus; 752 } 753 754 fTempPacket.data = static_cast<uint8_t*>(const_cast<void*>( 755 fChunkBuffer)); 756 fTempPacket.size = fChunkBufferSize; 757 758 fContext->reordered_opaque = chunkMediaHeader.start_time; 759 // Let ffmpeg handle the relationship between start_time and 760 // decoded video frame. 761 // 762 // Explanation: 763 // The received chunk buffer may not contain the next video 764 // frame to be decoded, due to frame reordering (e.g. MPEG1/2 765 // provides encoded video frames in a different order than the 766 // decoded video frame). 767 // 768 // FIXME: Research how to establish a meaningful relationship 769 // between start_time and decoded video frame when the received 770 // chunk buffer contains partial video frames. Maybe some data 771 // formats contain time stamps (ake pts / dts fields) that can 772 // be evaluated by FFMPEG. But as long as I don't have such 773 // video data to test it, it makes no sense to implement it. 774 // 775 // FIXME: Implement tracking start_time of video frames 776 // originating in data chunks that encode more than one video 777 // frame at a time. In that case on would increment the 778 // start_time for each consecutive frame of such a data chunk 779 // (like it is done for audio frame decoding). But as long as 780 // I don't have such video data to test it, it makes no sense 781 // to implement it. 782 783 #ifdef LOG_STREAM_TO_FILE 784 if (sDumpedPackets < 100) { 785 sStreamLogFile.Write(fChunkBuffer, fChunkBufferSize); 786 printf("wrote %ld bytes\n", fChunkBufferSize); 787 sDumpedPackets++; 788 } else if (sDumpedPackets == 100) 789 sStreamLogFile.Unset(); 790 #endif 791 } 792 793 #if DO_PROFILING 794 bigtime_t startTime = system_time(); 795 #endif 796 797 // NOTE: In the FFMPEG 0.10.2 code example decoding_encoding.c, the 798 // length returned by avcodec_decode_video2() is used to update the 799 // packet buffer size (here it is fTempPacket.size). This way the 800 // packet buffer is allowed to contain incomplete frames so we are 801 // required to buffer the packets between different calls to 802 // _DecodeNextVideoFrame(). 803 int gotPicture = 0; 804 int decodedDataSizeInBytes = avcodec_decode_video2(fContext, 805 fRawDecodedPicture, &gotPicture, &fTempPacket); 806 if (decodedDataSizeInBytes < 0) { 807 TRACE("[v] AVCodecDecoder: ignoring error in decoding frame %lld:" 808 " %d\n", fFrame, len); 809 // NOTE: An error from avcodec_decode_video2() is ignored by the 810 // FFMPEG 0.10.2 example decoding_encoding.c. Only the packet 811 // buffers are flushed accordingly 812 fTempPacket.data = NULL; 813 fTempPacket.size = 0; 814 continue; 815 } 816 817 fTempPacket.size -= decodedDataSizeInBytes; 818 fTempPacket.data += decodedDataSizeInBytes; 819 820 //TRACE("FFDEC: PTS = %d:%d:%d.%d - fContext->frame_number = %ld " 821 // "fContext->frame_rate = %ld\n", (int)(fContext->pts / (60*60*1000000)), 822 // (int)(fContext->pts / (60*1000000)), (int)(fContext->pts / (1000000)), 823 // (int)(fContext->pts % 1000000), fContext->frame_number, 824 // fContext->frame_rate); 825 //TRACE("FFDEC: PTS = %d:%d:%d.%d - fContext->frame_number = %ld " 826 // "fContext->frame_rate = %ld\n", 827 // (int)(fRawDecodedPicture->pts / (60*60*1000000)), 828 // (int)(fRawDecodedPicture->pts / (60*1000000)), 829 // (int)(fRawDecodedPicture->pts / (1000000)), 830 // (int)(fRawDecodedPicture->pts % 1000000), fContext->frame_number, 831 // fContext->frame_rate); 832 833 if (gotPicture) { 834 #if DO_PROFILING 835 bigtime_t formatConversionStart = system_time(); 836 #endif 837 // TRACE("ONE FRAME OUT !! len=%d size=%ld (%s)\n", len, size, 838 // pixfmt_to_string(fContext->pix_fmt)); 839 840 _UpdateMediaHeaderForVideoFrame(); 841 _DeinterlaceAndColorConvertVideoFrame(); 842 843 #ifdef DEBUG 844 dump_ffframe(fRawDecodedPicture, "ffpict"); 845 // dump_ffframe(fPostProcessedDecodedPicture, "opict"); 846 #endif 847 fFrame++; 848 849 #if DO_PROFILING 850 bigtime_t doneTime = system_time(); 851 decodingTime += formatConversionStart - startTime; 852 conversionTime += doneTime - formatConversionStart; 853 profileCounter++; 854 if (!(fFrame % 5)) { 855 if (info) { 856 printf("[v] profile: d1 = %lld, d2 = %lld (%lld) required " 857 "%Ld\n", 858 decodingTime / profileCounter, 859 conversionTime / profileCounter, 860 fFrame, info->time_to_decode); 861 } else { 862 printf("[v] profile: d1 = %lld, d2 = %lld (%lld) required " 863 "%Ld\n", 864 decodingTime / profileCounter, 865 conversionTime / profileCounter, 866 fFrame, bigtime_t(1000000LL / fOutputFrameRate)); 867 } 868 decodingTime = 0; 869 conversionTime = 0; 870 profileCounter = 0; 871 } 872 #endif 873 return B_OK; 874 } else { 875 TRACE("frame %lld - no picture yet, len: %d, chunk size: %ld\n", 876 fFrame, len, size); 877 } 878 } 879 } 880 881 882 /*! \brief Updates relevant fields of the class member fHeader with the properties of 883 the most recently decoded video frame. 884 885 It is assumed that this function is called in _DecodeNextVideoFrame() only 886 when the following asserts hold true: 887 1. We actually got a new picture decoded by the video decoder. 888 2. fHeader wasn't updated for the new picture yet. You MUST call this 889 method only once per decoded video frame. 890 3. This function MUST be called before 891 _DeinterlaceAndColorConvertVideoFrame() as the later one relys on an 892 updated fHeader. 893 4. There will be at maximumn only one decoded video frame in our cache 894 at any single point in time. Otherwise you couldn't tell to which 895 cached decoded video frame the properties in fHeader relate to. 896 */ 897 void 898 AVCodecDecoder::_UpdateMediaHeaderForVideoFrame() 899 { 900 fHeader.type = B_MEDIA_RAW_VIDEO; 901 fHeader.file_pos = 0; 902 fHeader.orig_size = 0; 903 fHeader.start_time = fRawDecodedPicture->reordered_opaque; 904 fHeader.u.raw_video.field_gamma = 1.0; 905 fHeader.u.raw_video.field_sequence = fFrame; 906 fHeader.u.raw_video.field_number = 0; 907 fHeader.u.raw_video.pulldown_number = 0; 908 fHeader.u.raw_video.first_active_line = 1; 909 fHeader.u.raw_video.line_count = fRawDecodedPicture->height; 910 911 TRACE("[v] start_time=%02d:%02d.%02d field_sequence=%lu\n", 912 int((fHeader.start_time / 60000000) % 60), 913 int((fHeader.start_time / 1000000) % 60), 914 int((fHeader.start_time / 10000) % 100), 915 fHeader.u.raw_video.field_sequence); 916 } 917 918 919 /*! \brief This function applies deinterlacing (only if needed) and color conversion 920 to the video frame in fRawDecodedPicture. 921 922 It is assumed that fRawDecodedPicture wasn't deinterlaced and color 923 converted yet (otherwise this function behaves in unknown manners). 924 925 You should only call this function in _DecodeNextVideoFrame() when we 926 got a new picture decoded by the video decoder and the fHeader variable was 927 updated accordingly (@see _UpdateMediaHeaderForVideoFrame()). 928 929 When this function finishes the postprocessed video frame will be available 930 in fPostProcessedDecodedPicture and fDecodedData (fDecodedDataSizeInBytes 931 will be set accordingly). 932 */ 933 void 934 AVCodecDecoder::_DeinterlaceAndColorConvertVideoFrame() 935 { 936 int width = fOutputVideoFormat.display.line_width; 937 int height = fOutputVideoFormat.display.line_count; 938 AVPicture deinterlacedPicture; 939 bool useDeinterlacedPicture = false; 940 941 if (fRawDecodedPicture->interlaced_frame) { 942 AVPicture rawPicture; 943 rawPicture.data[0] = fRawDecodedPicture->data[0]; 944 rawPicture.data[1] = fRawDecodedPicture->data[1]; 945 rawPicture.data[2] = fRawDecodedPicture->data[2]; 946 rawPicture.data[3] = fRawDecodedPicture->data[3]; 947 rawPicture.linesize[0] = fRawDecodedPicture->linesize[0]; 948 rawPicture.linesize[1] = fRawDecodedPicture->linesize[1]; 949 rawPicture.linesize[2] = fRawDecodedPicture->linesize[2]; 950 rawPicture.linesize[3] = fRawDecodedPicture->linesize[3]; 951 952 avpicture_alloc(&deinterlacedPicture, 953 fContext->pix_fmt, width, height); 954 955 if (avpicture_deinterlace(&deinterlacedPicture, &rawPicture, 956 fContext->pix_fmt, width, height) < 0) { 957 TRACE("[v] avpicture_deinterlace() - error\n"); 958 } else 959 useDeinterlacedPicture = true; 960 } 961 962 // Some decoders do not set pix_fmt until they have decoded 1 frame 963 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION 964 if (fSwsContext == NULL) { 965 fSwsContext = sws_getContext(fContext->width, fContext->height, 966 fContext->pix_fmt, fContext->width, fContext->height, 967 colorspace_to_pixfmt(fOutputVideoFormat.display.format), 968 SWS_FAST_BILINEAR, NULL, NULL, NULL); 969 } 970 #else 971 if (fFormatConversionFunc == NULL) { 972 fFormatConversionFunc = resolve_colorspace( 973 fOutputVideoFormat.display.format, fContext->pix_fmt, 974 fContext->width, fContext->height); 975 } 976 #endif 977 978 fDecodedDataSizeInBytes = avpicture_get_size( 979 colorspace_to_pixfmt(fOutputVideoFormat.display.format), 980 fContext->width, fContext->height); 981 982 if (fDecodedData == NULL) 983 fDecodedData 984 = static_cast<uint8_t*>(malloc(fDecodedDataSizeInBytes)); 985 986 fPostProcessedDecodedPicture->data[0] = fDecodedData; 987 fPostProcessedDecodedPicture->linesize[0] 988 = fOutputVideoFormat.display.bytes_per_row; 989 990 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION 991 if (fSwsContext != NULL) { 992 #else 993 if (fFormatConversionFunc != NULL) { 994 #endif 995 if (useDeinterlacedPicture) { 996 AVFrame deinterlacedFrame; 997 deinterlacedFrame.data[0] = deinterlacedPicture.data[0]; 998 deinterlacedFrame.data[1] = deinterlacedPicture.data[1]; 999 deinterlacedFrame.data[2] = deinterlacedPicture.data[2]; 1000 deinterlacedFrame.data[3] = deinterlacedPicture.data[3]; 1001 deinterlacedFrame.linesize[0] 1002 = deinterlacedPicture.linesize[0]; 1003 deinterlacedFrame.linesize[1] 1004 = deinterlacedPicture.linesize[1]; 1005 deinterlacedFrame.linesize[2] 1006 = deinterlacedPicture.linesize[2]; 1007 deinterlacedFrame.linesize[3] 1008 = deinterlacedPicture.linesize[3]; 1009 1010 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION 1011 sws_scale(fSwsContext, deinterlacedFrame.data, 1012 deinterlacedFrame.linesize, 0, fContext->height, 1013 fPostProcessedDecodedPicture->data, 1014 fPostProcessedDecodedPicture->linesize); 1015 #else 1016 (*fFormatConversionFunc)(&deinterlacedFrame, 1017 fPostProcessedDecodedPicture, width, height); 1018 #endif 1019 } else { 1020 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION 1021 sws_scale(fSwsContext, fRawDecodedPicture->data, 1022 fRawDecodedPicture->linesize, 0, fContext->height, 1023 fPostProcessedDecodedPicture->data, 1024 fPostProcessedDecodedPicture->linesize); 1025 #else 1026 (*fFormatConversionFunc)(fRawDecodedPicture, 1027 fPostProcessedDecodedPicture, width, height); 1028 #endif 1029 } 1030 } 1031 1032 if (fRawDecodedPicture->interlaced_frame) 1033 avpicture_free(&deinterlacedPicture); 1034 } 1035