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 * Copyright (C) 2015 Adrien Destugues <pulkomandy@pulkomandy.tk> 9 * 10 * All rights reserved. Distributed under the terms of the MIT License. 11 */ 12 13 //! libavcodec based decoder for Haiku 14 15 16 #include "AVCodecDecoder.h" 17 18 #include <new> 19 20 #include <assert.h> 21 #include <string.h> 22 23 #include <Bitmap.h> 24 #include <Debug.h> 25 #include <String.h> 26 27 #include "Utilities.h" 28 29 30 #undef TRACE 31 //#define TRACE_AV_CODEC 32 #ifdef TRACE_AV_CODEC 33 # define TRACE(x...) printf(x) 34 # define TRACE_AUDIO(x...) printf(x) 35 # define TRACE_VIDEO(x...) printf(x) 36 #else 37 # define TRACE(x...) 38 # define TRACE_AUDIO(x...) 39 # define TRACE_VIDEO(x...) 40 #endif 41 42 //#define LOG_STREAM_TO_FILE 43 #ifdef LOG_STREAM_TO_FILE 44 # include <File.h> 45 static BFile sAudioStreamLogFile( 46 "/boot/home/Desktop/AVCodecDebugAudioStream.raw", 47 B_CREATE_FILE | B_ERASE_FILE | B_WRITE_ONLY); 48 static BFile sVideoStreamLogFile( 49 "/boot/home/Desktop/AVCodecDebugVideoStream.raw", 50 B_CREATE_FILE | B_ERASE_FILE | B_WRITE_ONLY); 51 static int sDumpedPackets = 0; 52 #endif 53 54 typedef AVCodecID CodecID; 55 56 struct wave_format_ex { 57 uint16 format_tag; 58 uint16 channels; 59 uint32 frames_per_sec; 60 uint32 avg_bytes_per_sec; 61 uint16 block_align; 62 uint16 bits_per_sample; 63 uint16 extra_size; 64 // extra_data[extra_size] 65 } _PACKED; 66 67 struct avformat_codec_context { 68 int sample_rate; 69 int channels; 70 }; 71 72 73 // profiling related globals 74 #define DO_PROFILING 0 75 #if DO_PROFILING 76 static bigtime_t decodingTime = 0; 77 static bigtime_t conversionTime = 0; 78 static long profileCounter = 0; 79 #endif 80 81 82 AVCodecDecoder::AVCodecDecoder() 83 : 84 fHeader(), 85 fInputFormat(), 86 fFrame(0), 87 fIsAudio(false), 88 fCodec(NULL), 89 fCodecContext(avcodec_alloc_context3(NULL)), 90 fResampleContext(NULL), 91 fDecodedData(NULL), 92 fDecodedDataSizeInBytes(0), 93 fPostProcessedDecodedPicture(av_frame_alloc()), 94 fRawDecodedPicture(av_frame_alloc()), 95 fRawDecodedAudio(av_frame_alloc()), 96 97 fCodecInitDone(false), 98 99 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION 100 fSwsContext(NULL), 101 #else 102 fFormatConversionFunc(NULL), 103 #endif 104 105 fExtraData(NULL), 106 fExtraDataSize(0), 107 fBlockAlign(0), 108 109 fOutputColorSpace(B_NO_COLOR_SPACE), 110 fOutputFrameCount(0), 111 fOutputFrameRate(1.0), 112 fOutputFrameSize(0), 113 fInputFrameSize(0), 114 115 fChunkBuffer(NULL), 116 fChunkBufferSize(0), 117 fAudioDecodeError(false), 118 119 fDecodedDataBuffer(av_frame_alloc()), 120 fDecodedDataBufferOffset(0), 121 fDecodedDataBufferSize(0), 122 fBufferSinkContext(NULL), 123 fBufferSourceContext(NULL), 124 fFilterGraph(NULL), 125 fFilterFrame(NULL) 126 { 127 TRACE("AVCodecDecoder::AVCodecDecoder()\n"); 128 129 system_info info; 130 get_system_info(&info); 131 132 fCodecContext->err_recognition = AV_EF_CAREFUL; 133 fCodecContext->error_concealment = 3; 134 fCodecContext->thread_count = info.cpu_count; 135 } 136 137 138 AVCodecDecoder::~AVCodecDecoder() 139 { 140 TRACE("[%c] AVCodecDecoder::~AVCodecDecoder()\n", fIsAudio?('a'):('v')); 141 142 #if DO_PROFILING 143 if (profileCounter > 0) { 144 printf("[%c] profile: d1 = %lld, d2 = %lld (%Ld)\n", 145 fIsAudio?('a'):('v'), decodingTime / profileCounter, 146 conversionTime / profileCounter, fFrame); 147 } 148 #endif 149 150 if (fCodecInitDone) 151 avcodec_close(fCodecContext); 152 153 swr_free(&fResampleContext); 154 free(fChunkBuffer); 155 free(fDecodedData); 156 157 av_free(fPostProcessedDecodedPicture); 158 av_free(fRawDecodedPicture); 159 av_free(fRawDecodedAudio->opaque); 160 av_free(fRawDecodedAudio); 161 av_free(fCodecContext); 162 av_free(fDecodedDataBuffer); 163 164 av_frame_free(&fFilterFrame); 165 avfilter_graph_free(&fFilterGraph); 166 167 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION 168 if (fSwsContext != NULL) 169 sws_freeContext(fSwsContext); 170 #endif 171 172 delete[] fExtraData; 173 } 174 175 176 void 177 AVCodecDecoder::GetCodecInfo(media_codec_info* mci) 178 { 179 snprintf(mci->short_name, 32, "%s", fCodec->name); 180 snprintf(mci->pretty_name, 96, "%s", fCodec->long_name); 181 mci->id = 0; 182 mci->sub_id = fCodec->id; 183 } 184 185 186 status_t 187 AVCodecDecoder::Setup(media_format* ioEncodedFormat, const void* infoBuffer, 188 size_t infoSize) 189 { 190 if (ioEncodedFormat->type != B_MEDIA_ENCODED_AUDIO 191 && ioEncodedFormat->type != B_MEDIA_ENCODED_VIDEO) 192 return B_ERROR; 193 194 fIsAudio = (ioEncodedFormat->type == B_MEDIA_ENCODED_AUDIO); 195 TRACE("[%c] AVCodecDecoder::Setup()\n", fIsAudio?('a'):('v')); 196 197 #ifdef TRACE_AV_CODEC 198 char buffer[1024]; 199 string_for_format(*ioEncodedFormat, buffer, sizeof(buffer)); 200 TRACE("[%c] input_format = %s\n", fIsAudio?('a'):('v'), buffer); 201 TRACE("[%c] infoSize = %ld\n", fIsAudio?('a'):('v'), infoSize); 202 TRACE("[%c] user_data_type = %08lx\n", fIsAudio?('a'):('v'), 203 ioEncodedFormat->user_data_type); 204 TRACE("[%c] meta_data_size = %ld\n", fIsAudio?('a'):('v'), 205 ioEncodedFormat->MetaDataSize()); 206 #endif 207 208 media_format_description description; 209 if (BMediaFormats().GetCodeFor(*ioEncodedFormat, 210 B_MISC_FORMAT_FAMILY, &description) == B_OK) { 211 if (description.u.misc.file_format != 'ffmp') 212 return B_NOT_SUPPORTED; 213 fCodec = avcodec_find_decoder(static_cast<CodecID>( 214 description.u.misc.codec)); 215 if (fCodec == NULL) { 216 TRACE(" unable to find the correct FFmpeg " 217 "decoder (id = %lu)\n", description.u.misc.codec); 218 return B_ERROR; 219 } 220 TRACE(" found decoder %s\n", fCodec->name); 221 222 const void* extraData = infoBuffer; 223 fExtraDataSize = infoSize; 224 if (description.family == B_WAV_FORMAT_FAMILY 225 && infoSize >= sizeof(wave_format_ex)) { 226 TRACE(" trying to use wave_format_ex\n"); 227 // Special case extra data in B_WAV_FORMAT_FAMILY 228 const wave_format_ex* waveFormatData 229 = (const wave_format_ex*)infoBuffer; 230 231 size_t waveFormatSize = infoSize; 232 if (waveFormatData != NULL && waveFormatSize > 0) { 233 fBlockAlign = waveFormatData->block_align; 234 TRACE(" found block align: %d\n", fBlockAlign); 235 fExtraDataSize = waveFormatData->extra_size; 236 // skip the wave_format_ex from the extra data. 237 extraData = waveFormatData + 1; 238 } 239 } else { 240 if (fIsAudio) { 241 fBlockAlign 242 = ioEncodedFormat->u.encoded_audio.output.buffer_size; 243 TRACE(" using buffer_size as block align: %d\n", 244 fBlockAlign); 245 } 246 } 247 if (extraData != NULL && fExtraDataSize > 0) { 248 TRACE("AVCodecDecoder: extra data size %ld\n", infoSize); 249 delete[] fExtraData; 250 fExtraData = new(std::nothrow) char[fExtraDataSize]; 251 if (fExtraData != NULL) 252 memcpy(fExtraData, infoBuffer, fExtraDataSize); 253 else 254 fExtraDataSize = 0; 255 } 256 257 fInputFormat = *ioEncodedFormat; 258 return B_OK; 259 } else { 260 TRACE("AVCodecDecoder: BMediaFormats().GetCodeFor() failed.\n"); 261 } 262 263 printf("AVCodecDecoder::Setup failed!\n"); 264 return B_ERROR; 265 } 266 267 268 status_t 269 AVCodecDecoder::SeekedTo(int64 frame, bigtime_t time) 270 { 271 status_t ret = B_OK; 272 // Reset the FFmpeg codec to flush buffers, so we keep the sync 273 if (fCodecInitDone) { 274 avcodec_flush_buffers(fCodecContext); 275 _ResetTempPacket(); 276 } 277 278 // Flush internal buffers as well. 279 free(fChunkBuffer); 280 fChunkBuffer = NULL; 281 fChunkBufferSize = 0; 282 fDecodedDataBufferOffset = 0; 283 fDecodedDataBufferSize = 0; 284 fDecodedDataSizeInBytes = 0; 285 286 fFrame = frame; 287 288 return ret; 289 } 290 291 292 status_t 293 AVCodecDecoder::NegotiateOutputFormat(media_format* inOutFormat) 294 { 295 TRACE("AVCodecDecoder::NegotiateOutputFormat() [%c] \n", 296 fIsAudio?('a'):('v')); 297 298 #ifdef TRACE_AV_CODEC 299 char buffer[1024]; 300 string_for_format(*inOutFormat, buffer, sizeof(buffer)); 301 TRACE(" [%c] requested format = %s\n", fIsAudio?('a'):('v'), buffer); 302 #endif 303 304 if (fIsAudio) 305 return _NegotiateAudioOutputFormat(inOutFormat); 306 else 307 return _NegotiateVideoOutputFormat(inOutFormat); 308 } 309 310 311 status_t 312 AVCodecDecoder::Decode(void* outBuffer, int64* outFrameCount, 313 media_header* mediaHeader, media_decode_info* info) 314 { 315 if (!fCodecInitDone) 316 return B_NO_INIT; 317 318 status_t ret; 319 if (fIsAudio) 320 ret = _DecodeAudio(outBuffer, outFrameCount, mediaHeader, info); 321 else 322 ret = _DecodeVideo(outBuffer, outFrameCount, mediaHeader, info); 323 324 return ret; 325 } 326 327 328 // #pragma mark - 329 330 331 void 332 AVCodecDecoder::_ResetTempPacket() 333 { 334 av_init_packet(&fTempPacket); 335 fTempPacket.size = 0; 336 fTempPacket.data = NULL; 337 } 338 339 340 status_t 341 AVCodecDecoder::_NegotiateAudioOutputFormat(media_format* inOutFormat) 342 { 343 TRACE("AVCodecDecoder::_NegotiateAudioOutputFormat()\n"); 344 345 _ApplyEssentialAudioContainerPropertiesToContext(); 346 // This makes audio formats play that encode the audio properties in 347 // the audio container (e.g. WMA) and not in the audio frames 348 // themself (e.g. MP3). 349 // Note: Doing this step unconditionally is OK, because the first call 350 // to _DecodeNextAudioFrameChunk() will update the essential audio 351 // format properties accordingly regardless of the settings here. 352 353 // close any previous instance 354 if (fCodecInitDone) { 355 fCodecInitDone = false; 356 avcodec_close(fCodecContext); 357 } 358 359 if (avcodec_open2(fCodecContext, fCodec, NULL) >= 0) 360 fCodecInitDone = true; 361 else { 362 TRACE("avcodec_open() failed to init codec!\n"); 363 return B_ERROR; 364 } 365 366 free(fChunkBuffer); 367 fChunkBuffer = NULL; 368 fChunkBufferSize = 0; 369 fAudioDecodeError = false; 370 fDecodedDataBufferOffset = 0; 371 fDecodedDataBufferSize = 0; 372 373 _ResetTempPacket(); 374 375 status_t statusOfDecodingFirstFrameChunk = _DecodeNextAudioFrameChunk(); 376 if (statusOfDecodingFirstFrameChunk != B_OK) { 377 TRACE("[a] decoding first audio frame chunk failed\n"); 378 return B_ERROR; 379 } 380 381 media_multi_audio_format outputAudioFormat; 382 outputAudioFormat = media_raw_audio_format::wildcard; 383 outputAudioFormat.byte_order = B_MEDIA_HOST_ENDIAN; 384 outputAudioFormat.frame_rate = fCodecContext->sample_rate; 385 outputAudioFormat.channel_count = fCodecContext->channels; 386 ConvertAVSampleFormatToRawAudioFormat(fCodecContext->sample_fmt, 387 outputAudioFormat.format); 388 // Check that format is not still a wild card! 389 if (outputAudioFormat.format == 0) { 390 TRACE(" format still a wild-card, assuming B_AUDIO_SHORT.\n"); 391 outputAudioFormat.format = media_raw_audio_format::B_AUDIO_SHORT; 392 } 393 outputAudioFormat.buffer_size = inOutFormat->u.raw_audio.buffer_size; 394 // Check that buffer_size has a sane value 395 size_t sampleSize = outputAudioFormat.format 396 & media_raw_audio_format::B_AUDIO_SIZE_MASK; 397 if (outputAudioFormat.buffer_size == 0) { 398 outputAudioFormat.buffer_size = 512 * sampleSize 399 * outputAudioFormat.channel_count; 400 } 401 402 inOutFormat->type = B_MEDIA_RAW_AUDIO; 403 inOutFormat->u.raw_audio = outputAudioFormat; 404 inOutFormat->require_flags = 0; 405 inOutFormat->deny_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS; 406 407 // Initialize variables needed to manage decoding as much audio frames as 408 // needed to fill the buffer_size. 409 fOutputFrameSize = sampleSize * outputAudioFormat.channel_count; 410 fOutputFrameCount = outputAudioFormat.buffer_size / fOutputFrameSize; 411 fOutputFrameRate = outputAudioFormat.frame_rate; 412 if (av_sample_fmt_is_planar(fCodecContext->sample_fmt)) 413 fInputFrameSize = sampleSize; 414 else 415 fInputFrameSize = fOutputFrameSize; 416 417 fRawDecodedAudio->opaque 418 = av_realloc(fRawDecodedAudio->opaque, sizeof(avformat_codec_context)); 419 if (fRawDecodedAudio->opaque == NULL) 420 return B_NO_MEMORY; 421 422 if (av_sample_fmt_is_planar(fCodecContext->sample_fmt)) { 423 fResampleContext = swr_alloc_set_opts(NULL, 424 fCodecContext->channel_layout, 425 fCodecContext->request_sample_fmt, 426 fCodecContext->sample_rate, 427 fCodecContext->channel_layout, 428 fCodecContext->sample_fmt, 429 fCodecContext->sample_rate, 430 0, NULL); 431 swr_init(fResampleContext); 432 } 433 434 TRACE(" bit_rate = %d, sample_rate = %d, channels = %d, " 435 "output frame size: %d, count: %ld, rate: %.2f\n", 436 fCodecContext->bit_rate, fCodecContext->sample_rate, fCodecContext->channels, 437 fOutputFrameSize, fOutputFrameCount, fOutputFrameRate); 438 439 return B_OK; 440 } 441 442 443 status_t 444 AVCodecDecoder::_NegotiateVideoOutputFormat(media_format* inOutFormat) 445 { 446 TRACE("AVCodecDecoder::_NegotiateVideoOutputFormat()\n"); 447 448 TRACE(" requested video format 0x%x\n", 449 inOutFormat->u.raw_video.display.format); 450 451 _ApplyEssentialVideoContainerPropertiesToContext(); 452 // This makes video formats play that encode the video properties in 453 // the video container (e.g. WMV) and not in the video frames 454 // themself (e.g. MPEG2). 455 // Note: Doing this step unconditionally is OK, because the first call 456 // to _DecodeNextVideoFrame() will update the essential video format 457 // properties accordingly regardless of the settings here. 458 459 bool codecCanHandleIncompleteFrames 460 = (fCodec->capabilities & AV_CODEC_CAP_TRUNCATED) != 0; 461 if (codecCanHandleIncompleteFrames) { 462 // Expect and handle video frames to be splitted across consecutive 463 // data chunks. 464 fCodecContext->flags |= AV_CODEC_FLAG_TRUNCATED; 465 } 466 467 // close any previous instance 468 if (fCodecInitDone) { 469 fCodecInitDone = false; 470 avcodec_close(fCodecContext); 471 } 472 473 if (avcodec_open2(fCodecContext, fCodec, NULL) >= 0) 474 fCodecInitDone = true; 475 else { 476 TRACE("avcodec_open() failed to init codec!\n"); 477 return B_ERROR; 478 } 479 480 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION 481 fOutputColorSpace = B_RGB32; 482 #else 483 // Make MediaPlayer happy (if not in rgb32 screen depth and no overlay, 484 // it will only ask for YCbCr, which DrawBitmap doesn't handle, so the 485 // default colordepth is RGB32). 486 if (inOutFormat->u.raw_video.display.format == B_YCbCr422) 487 fOutputColorSpace = B_YCbCr422; 488 else 489 fOutputColorSpace = B_RGB32; 490 #endif 491 492 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION 493 if (fSwsContext != NULL) 494 sws_freeContext(fSwsContext); 495 fSwsContext = NULL; 496 #else 497 fFormatConversionFunc = 0; 498 #endif 499 500 free(fChunkBuffer); 501 fChunkBuffer = NULL; 502 fChunkBufferSize = 0; 503 504 _ResetTempPacket(); 505 506 status_t statusOfDecodingFirstFrame = _DecodeNextVideoFrame(); 507 if (statusOfDecodingFirstFrame != B_OK) { 508 TRACE("[v] decoding first video frame failed\n"); 509 return B_ERROR; 510 } 511 512 // Note: fSwsContext / fFormatConversionFunc should have been initialized 513 // by first call to _DecodeNextVideoFrame() above. 514 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION 515 if (fSwsContext == NULL) { 516 TRACE("No SWS Scale context or decoder has not set the pixel format " 517 "yet!\n"); 518 } 519 #else 520 if (fFormatConversionFunc == NULL) { 521 TRACE("no pixel format conversion function found or decoder has " 522 "not set the pixel format yet!\n"); 523 } 524 #endif 525 526 inOutFormat->type = B_MEDIA_RAW_VIDEO; 527 inOutFormat->require_flags = 0; 528 inOutFormat->deny_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS; 529 inOutFormat->u.raw_video = fInputFormat.u.encoded_video.output; 530 inOutFormat->u.raw_video.interlace = 1; 531 // Progressive (non-interlaced) video frames are delivered 532 inOutFormat->u.raw_video.first_active 533 = fHeader.u.raw_video.first_active_line; 534 inOutFormat->u.raw_video.last_active = fHeader.u.raw_video.line_count; 535 inOutFormat->u.raw_video.pixel_width_aspect 536 = fHeader.u.raw_video.pixel_width_aspect; 537 inOutFormat->u.raw_video.pixel_height_aspect 538 = fHeader.u.raw_video.pixel_height_aspect; 539 #if 0 540 // This was added by Colin Günther in order to handle streams with a 541 // variable frame rate. fOutputFrameRate is computed from the stream 542 // time_base, but it actually assumes a timebase equal to the FPS. As far 543 // as I can see, a stream with a variable frame rate would have a higher 544 // resolution time_base and increment the pts (presentation time) of each 545 // frame by a value bigger than one. 546 // 547 // Fixed rate stream: 548 // time_base = 1/50s, frame PTS = 1, 2, 3... (for 50Hz) 549 // 550 // Variable rate stream: 551 // time_base = 1/300s, frame PTS = 6, 12, 18, ... (for 50Hz) 552 // time_base = 1/300s, frame PTS = 5, 10, 15, ... (for 60Hz) 553 // 554 // The fOutputFrameRate currently does not take this into account and 555 // ignores the PTS. This results in playing the above sample at 300Hz 556 // instead of 50 or 60. 557 // 558 // However, comparing the PTS for two consecutive implies we have already 559 // decoded 2 frames, which may not be the case when this method is first 560 // called. 561 inOutFormat->u.raw_video.field_rate = fOutputFrameRate; 562 // Was calculated by first call to _DecodeNextVideoFrame() 563 #endif 564 inOutFormat->u.raw_video.display.format = fOutputColorSpace; 565 inOutFormat->u.raw_video.display.line_width 566 = fHeader.u.raw_video.display_line_width; 567 inOutFormat->u.raw_video.display.line_count 568 = fHeader.u.raw_video.display_line_count; 569 inOutFormat->u.raw_video.display.bytes_per_row 570 = fHeader.u.raw_video.bytes_per_row; 571 572 #ifdef TRACE_AV_CODEC 573 char buffer[1024]; 574 string_for_format(*inOutFormat, buffer, sizeof(buffer)); 575 TRACE("[v] outFormat = %s\n", buffer); 576 TRACE(" returned video format 0x%x\n", 577 inOutFormat->u.raw_video.display.format); 578 #endif 579 580 return B_OK; 581 } 582 583 584 /*! \brief Fills the outBuffer with one or more already decoded audio frames. 585 586 Besides the main duty described above, this method also fills out the other 587 output parameters as documented below. 588 589 \param outBuffer Pointer to the output buffer to copy the decoded audio 590 frames to. 591 \param outFrameCount Pointer to the output variable to assign the number of 592 copied audio frames (usually several audio frames at once). 593 \param mediaHeader Pointer to the output media header that contains the 594 properties of the decoded audio frame being the first in the outBuffer. 595 \param info Specifies additional decoding parameters. (Note: unused). 596 597 \returns B_OK Decoding audio frames succeeded. 598 \returns B_LAST_BUFFER_ERROR There are no more audio frames available. 599 \returns Other error codes 600 */ 601 status_t 602 AVCodecDecoder::_DecodeAudio(void* outBuffer, int64* outFrameCount, 603 media_header* mediaHeader, media_decode_info* info) 604 { 605 TRACE_AUDIO("AVCodecDecoder::_DecodeAudio(audio start_time %.6fs)\n", 606 mediaHeader->start_time / 1000000.0); 607 608 status_t audioDecodingStatus 609 = fDecodedDataSizeInBytes > 0 ? B_OK : _DecodeNextAudioFrame(); 610 611 if (audioDecodingStatus != B_OK) 612 return audioDecodingStatus; 613 614 *outFrameCount = fDecodedDataSizeInBytes / fOutputFrameSize; 615 *mediaHeader = fHeader; 616 memcpy(outBuffer, fDecodedData, fDecodedDataSizeInBytes); 617 618 fDecodedDataSizeInBytes = 0; 619 620 return B_OK; 621 } 622 623 624 /*! \brief Fills the outBuffer with an already decoded video frame. 625 626 Besides the main duty described above, this method also fills out the other 627 output parameters as documented below. 628 629 \param outBuffer Pointer to the output buffer to copy the decoded video 630 frame to. 631 \param outFrameCount Pointer to the output variable to assign the number of 632 copied video frames (usually one video frame). 633 \param mediaHeader Pointer to the output media header that contains the 634 decoded video frame properties. 635 \param info Specifies additional decoding parameters. (Note: unused). 636 637 \returns B_OK Decoding a video frame succeeded. 638 \returns B_LAST_BUFFER_ERROR There are no more video frames available. 639 \returns Other error codes 640 */ 641 status_t 642 AVCodecDecoder::_DecodeVideo(void* outBuffer, int64* outFrameCount, 643 media_header* mediaHeader, media_decode_info* info) 644 { 645 status_t videoDecodingStatus 646 = fDecodedDataSizeInBytes > 0 ? B_OK : _DecodeNextVideoFrame(); 647 648 if (videoDecodingStatus != B_OK) 649 return videoDecodingStatus; 650 651 *outFrameCount = 1; 652 *mediaHeader = fHeader; 653 memcpy(outBuffer, fDecodedData, mediaHeader->size_used); 654 655 fDecodedDataSizeInBytes = 0; 656 657 return B_OK; 658 } 659 660 661 /*! \brief Decodes next audio frame. 662 663 We decode at least one audio frame into fDecodedData. To achieve this goal, 664 we might need to request several chunks of encoded data resulting in a 665 variable execution time of this function. 666 667 The length of the decoded audio frame(s) is stored in 668 fDecodedDataSizeInBytes. If this variable is greater than zero you can 669 assert that all audio frames in fDecodedData are valid. 670 671 It is assumed that the number of expected audio frames is stored in 672 fOutputFrameCount. So _DecodeNextAudioFrame() must be called only after 673 fOutputFrameCount has been set. 674 675 Note: fOutputFrameCount contains the maximum number of frames a caller 676 of BMediaDecoder::Decode() expects to receive. There is a direct 677 relationship between fOutputFrameCount and the buffer size a caller of 678 BMediaDecoder::Decode() will provide so we make sure to respect this limit 679 for fDecodedDataSizeInBytes. 680 681 On return with status code B_OK the following conditions hold true: 682 1. fDecodedData contains as much audio frames as the caller of 683 BMediaDecoder::Decode() expects. 684 2. fDecodedData contains lesser audio frames as the caller of 685 BMediaDecoder::Decode() expects only when one of the following 686 conditions hold true: 687 i No more audio frames left. Consecutive calls to 688 _DecodeNextAudioFrame() will then result in the return of 689 status code B_LAST_BUFFER_ERROR. 690 ii TODO: A change in the size of the audio frames. 691 3. fHeader is populated with the audio frame properties of the first 692 audio frame in fDecodedData. Especially the start_time field of 693 fHeader relates to that first audio frame. Start times of 694 consecutive audio frames in fDecodedData have to be calculated 695 manually (using the frame rate and the frame duration) if the 696 caller needs them. 697 698 TODO: Handle change of channel_count. Such a change results in a change of 699 the audio frame size and thus has different buffer requirements. 700 The most sane approach for implementing this is to return the audio frames 701 that were still decoded with the previous channel_count and inform the 702 client of BMediaDecoder::Decode() about the change so that it can adapt to 703 it. Furthermore we need to adapt our fDecodedData to the new buffer size 704 requirements accordingly. 705 706 \returns B_OK when we successfully decoded enough audio frames 707 \returns B_LAST_BUFFER_ERROR when there are no more audio frames available. 708 \returns Other Errors 709 */ 710 status_t 711 AVCodecDecoder::_DecodeNextAudioFrame() 712 { 713 assert(fTempPacket.size >= 0); 714 assert(fDecodedDataSizeInBytes == 0); 715 // _DecodeNextAudioFrame needs to be called on empty fDecodedData only! 716 // If this assert holds wrong we have a bug somewhere. 717 718 status_t resetStatus = _ResetRawDecodedAudio(); 719 if (resetStatus != B_OK) 720 return resetStatus; 721 722 while (fRawDecodedAudio->nb_samples < fOutputFrameCount) { 723 _CheckAndFixConditionsThatHintAtBrokenAudioCodeBelow(); 724 725 bool decodedDataBufferHasData = fDecodedDataBufferSize > 0; 726 if (decodedDataBufferHasData) { 727 _MoveAudioFramesToRawDecodedAudioAndUpdateStartTimes(); 728 continue; 729 } 730 731 status_t decodeAudioChunkStatus = _DecodeNextAudioFrameChunk(); 732 if (decodeAudioChunkStatus != B_OK) 733 return decodeAudioChunkStatus; 734 } 735 736 fFrame += fRawDecodedAudio->nb_samples; 737 fDecodedDataSizeInBytes = fRawDecodedAudio->linesize[0]; 738 739 _UpdateMediaHeaderForAudioFrame(); 740 741 #ifdef DEBUG 742 dump_ffframe_audio(fRawDecodedAudio, "ffaudi"); 743 #endif 744 745 TRACE_AUDIO(" frame count: %ld current: %lld\n", 746 fRawDecodedAudio->nb_samples, fFrame); 747 748 return B_OK; 749 } 750 751 752 /*! \brief Applies all essential audio input properties to fCodecContext that were 753 passed to AVCodecDecoder when Setup() was called. 754 755 Note: This function must be called before the AVCodec is opened via 756 avcodec_open2(). Otherwise the behaviour of FFMPEG's audio decoding 757 function avcodec_decode_audio4() is undefined. 758 759 Essential properties applied from fInputFormat.u.encoded_audio: 760 - bit_rate copied to fCodecContext->bit_rate 761 - frame_size copied to fCodecContext->frame_size 762 - output.format converted to fCodecContext->sample_fmt 763 - output.frame_rate copied to fCodecContext->sample_rate 764 - output.channel_count copied to fCodecContext->channels 765 766 Other essential properties being applied: 767 - fBlockAlign to fCodecContext->block_align 768 - fExtraData to fCodecContext->extradata 769 - fExtraDataSize to fCodecContext->extradata_size 770 771 TODO: Either the following documentation section should be removed or this 772 TODO when it is clear whether fInputFormat.MetaData() and 773 fInputFormat.MetaDataSize() have to be applied to fCodecContext. See the related 774 TODO in the method implementation. 775 Only applied when fInputFormat.MetaDataSize() is greater than zero: 776 - fInputFormat.MetaData() to fCodecContext->extradata 777 - fInputFormat.MetaDataSize() to fCodecContext->extradata_size 778 */ 779 void 780 AVCodecDecoder::_ApplyEssentialAudioContainerPropertiesToContext() 781 { 782 media_encoded_audio_format containerProperties 783 = fInputFormat.u.encoded_audio; 784 785 fCodecContext->bit_rate 786 = static_cast<int>(containerProperties.bit_rate); 787 fCodecContext->frame_size 788 = static_cast<int>(containerProperties.frame_size); 789 ConvertRawAudioFormatToAVSampleFormat( 790 containerProperties.output.format, fCodecContext->sample_fmt); 791 ConvertRawAudioFormatToAVSampleFormat( 792 containerProperties.output.format, fCodecContext->request_sample_fmt); 793 fCodecContext->sample_rate 794 = static_cast<int>(containerProperties.output.frame_rate); 795 fCodecContext->channels 796 = static_cast<int>(containerProperties.output.channel_count); 797 // Check that channel count is not still a wild card! 798 if (fCodecContext->channels == 0) { 799 TRACE(" channel_count still a wild-card, assuming stereo.\n"); 800 fCodecContext->channels = 2; 801 } 802 803 fCodecContext->block_align = fBlockAlign; 804 fCodecContext->extradata = reinterpret_cast<uint8_t*>(fExtraData); 805 fCodecContext->extradata_size = fExtraDataSize; 806 807 // TODO: This probably needs to go away, there is some misconception 808 // about extra data / info buffer and meta data. See 809 // Reader::GetStreamInfo(). The AVFormatReader puts extradata and 810 // extradata_size into media_format::MetaData(), but used to ignore 811 // the infoBuffer passed to GetStreamInfo(). I think this may be why 812 // the code below was added. 813 if (fInputFormat.MetaDataSize() > 0) { 814 fCodecContext->extradata = static_cast<uint8_t*>( 815 const_cast<void*>(fInputFormat.MetaData())); 816 fCodecContext->extradata_size = fInputFormat.MetaDataSize(); 817 } 818 819 TRACE(" bit_rate %d, sample_rate %d, channels %d, block_align %d, " 820 "extradata_size %d\n", 821 fCodecContext->bit_rate, 822 fCodecContext->sample_rate, 823 fCodecContext->channels, 824 fCodecContext->block_align, 825 fCodecContext->extradata_size); 826 } 827 828 829 /*! \brief Resets important fields in fRawDecodedVideo to their default values. 830 831 Note: Also initializes fDecodedData if not done already. 832 833 \returns B_OK Resetting successfully completed. 834 \returns B_NO_MEMORY No memory left for correct operation. 835 */ 836 status_t 837 AVCodecDecoder::_ResetRawDecodedAudio() 838 { 839 if (fDecodedData == NULL) { 840 size_t maximumSizeOfDecodedData = fOutputFrameCount * fOutputFrameSize; 841 fDecodedData 842 = static_cast<uint8_t*>(malloc(maximumSizeOfDecodedData)); 843 } 844 if (fDecodedData == NULL) 845 return B_NO_MEMORY; 846 847 fRawDecodedAudio->data[0] = fDecodedData; 848 fRawDecodedAudio->linesize[0] = 0; 849 fRawDecodedAudio->format = AV_SAMPLE_FMT_NONE; 850 fRawDecodedAudio->pkt_dts = AV_NOPTS_VALUE; 851 fRawDecodedAudio->nb_samples = 0; 852 memset(fRawDecodedAudio->opaque, 0, sizeof(avformat_codec_context)); 853 854 return B_OK; 855 } 856 857 858 /*! \brief Checks fDecodedDataBufferSize and fTempPacket for invalid values, 859 reports them and assigns valid values. 860 861 Note: This method is intended to be called before any code is executed that 862 deals with moving, loading or decoding any audio frames. 863 */ 864 void 865 AVCodecDecoder::_CheckAndFixConditionsThatHintAtBrokenAudioCodeBelow() 866 { 867 if (fDecodedDataBufferSize < 0) { 868 fprintf(stderr, "Decoding read past the end of the decoded data " 869 "buffer! %" B_PRId32 "\n", fDecodedDataBufferSize); 870 fDecodedDataBufferSize = 0; 871 } 872 if (fTempPacket.size < 0) { 873 fprintf(stderr, "Decoding read past the end of the temp packet! %d\n", 874 fTempPacket.size); 875 fTempPacket.size = 0; 876 } 877 } 878 879 880 /*! \brief Moves audio frames from fDecodedDataBuffer to fRawDecodedAudio (and 881 thus to fDecodedData) and updates the start times of fRawDecodedAudio, 882 fDecodedDataBuffer and fTempPacket accordingly. 883 884 When moving audio frames to fRawDecodedAudio this method also makes sure 885 that the following important fields of fRawDecodedAudio are populated and 886 updated with correct values: 887 - fRawDecodedAudio->data[0]: Points to first free byte of fDecodedData 888 - fRawDecodedAudio->linesize[0]: Total size of frames in fDecodedData 889 - fRawDecodedAudio->format: Format of first audio frame 890 - fRawDecodedAudio->pkt_dts: Start time of first audio frame 891 - fRawDecodedAudio->nb_samples: Number of audio frames 892 - fRawDecodedAudio->opaque: Contains the following fields for the first 893 audio frame: 894 - channels: Channel count of first audio frame 895 - sample_rate: Frame rate of first audio frame 896 897 This function assumes to be called only when the following assumptions 898 hold true: 899 1. There are decoded audio frames available in fDecodedDataBuffer 900 meaning that fDecodedDataBufferSize is greater than zero. 901 2. There is space left in fRawDecodedAudio to move some audio frames 902 in. This means that fRawDecodedAudio has lesser audio frames than 903 the maximum allowed (specified by fOutputFrameCount). 904 3. The audio frame rate is known so that we can calculate the time 905 range (covered by the moved audio frames) to update the start times 906 accordingly. 907 4. The field fRawDecodedAudio->opaque points to a memory block 908 representing a structure of type avformat_codec_context. 909 910 After this function returns the caller can safely make the following 911 assumptions: 912 1. The number of decoded audio frames in fDecodedDataBuffer is 913 decreased though it may still be greater then zero. 914 2. The number of frames in fRawDecodedAudio has increased and all 915 important fields are updated (see listing above). 916 3. Start times of fDecodedDataBuffer and fTempPacket were increased 917 with the time range covered by the moved audio frames. 918 919 Note: This function raises an exception (by calling the debugger), when 920 fDecodedDataBufferSize is not a multiple of fOutputFrameSize. 921 */ 922 void 923 AVCodecDecoder::_MoveAudioFramesToRawDecodedAudioAndUpdateStartTimes() 924 { 925 assert(fDecodedDataBufferSize > 0); 926 assert(fRawDecodedAudio->nb_samples < fOutputFrameCount); 927 assert(fOutputFrameRate > 0); 928 929 int32 outFrames = fOutputFrameCount - fRawDecodedAudio->nb_samples; 930 int32 inFrames = fDecodedDataBufferSize; 931 932 int32 frames = min_c(outFrames, inFrames); 933 if (frames == 0) 934 debugger("fDecodedDataBufferSize not multiple of frame size!"); 935 936 // Some decoders do not support format conversion on themselves, or use 937 // "planar" audio (each channel separated instead of interleaved samples). 938 // In that case, we use swresample to convert the data 939 if (av_sample_fmt_is_planar(fCodecContext->sample_fmt)) { 940 #if 0 941 const uint8_t* ptr[8]; 942 for (int i = 0; i < 8; i++) { 943 if (fDecodedDataBuffer->data[i] == NULL) 944 ptr[i] = NULL; 945 else 946 ptr[i] = fDecodedDataBuffer->data[i] + fDecodedDataBufferOffset; 947 } 948 949 // When there are more input frames than space in the output buffer, 950 // we could feed everything to swr and it would buffer the extra data. 951 // However, there is no easy way to flush that data without feeding more 952 // input, and it makes our timestamp computations fail. 953 // So, we feed only as much frames as we can get out, and handle the 954 // buffering ourselves. 955 // TODO Ideally, we should try to size our output buffer so that it can 956 // always hold all the output (swr provides helper functions for this) 957 inFrames = frames; 958 frames = swr_convert(fResampleContext, fRawDecodedAudio->data, 959 outFrames, ptr, inFrames); 960 961 if (frames < 0) 962 debugger("resampling failed"); 963 #else 964 // interleave planar audio with same format 965 uintptr_t out = (uintptr_t)fRawDecodedAudio->data[0]; 966 int32 offset = fDecodedDataBufferOffset; 967 for (int i = 0; i < frames; i++) { 968 for (int j = 0; j < fCodecContext->channels; j++) { 969 memcpy((void*)out, fDecodedDataBuffer->data[j] 970 + offset, fInputFrameSize); 971 out += fInputFrameSize; 972 } 973 offset += fInputFrameSize; 974 } 975 outFrames = frames; 976 inFrames = frames; 977 #endif 978 } else { 979 memcpy(fRawDecodedAudio->data[0], fDecodedDataBuffer->data[0] 980 + fDecodedDataBufferOffset, frames * fOutputFrameSize); 981 outFrames = frames; 982 inFrames = frames; 983 } 984 985 size_t remainingSize = inFrames * fInputFrameSize; 986 size_t decodedSize = outFrames * fOutputFrameSize; 987 fDecodedDataBufferSize -= inFrames; 988 989 bool firstAudioFramesCopiedToRawDecodedAudio 990 = fRawDecodedAudio->data[0] != fDecodedData; 991 if (!firstAudioFramesCopiedToRawDecodedAudio) { 992 fRawDecodedAudio->format = fDecodedDataBuffer->format; 993 fRawDecodedAudio->pkt_dts = fDecodedDataBuffer->pkt_dts; 994 995 avformat_codec_context* codecContext 996 = static_cast<avformat_codec_context*>(fRawDecodedAudio->opaque); 997 codecContext->channels = fCodecContext->channels; 998 codecContext->sample_rate = fCodecContext->sample_rate; 999 } 1000 1001 fRawDecodedAudio->data[0] += decodedSize; 1002 fRawDecodedAudio->linesize[0] += decodedSize; 1003 fRawDecodedAudio->nb_samples += outFrames; 1004 1005 fDecodedDataBufferOffset += remainingSize; 1006 1007 // Update start times accordingly 1008 bigtime_t framesTimeInterval = static_cast<bigtime_t>( 1009 (1000000LL * frames) / fOutputFrameRate); 1010 fDecodedDataBuffer->pkt_dts += framesTimeInterval; 1011 // Start time of buffer is updated in case that it contains 1012 // more audio frames to move. 1013 fTempPacket.dts += framesTimeInterval; 1014 // Start time of fTempPacket is updated in case the fTempPacket 1015 // contains more audio frames to decode. 1016 } 1017 1018 1019 /*! \brief Decodes next chunk of audio frames. 1020 1021 This method handles all the details of loading the input buffer 1022 (fChunkBuffer) at the right time and of calling FFMPEG often engouh until 1023 some audio frames have been decoded. 1024 1025 FFMPEG decides how much audio frames belong to a chunk. Because of that 1026 it is very likely that _DecodeNextAudioFrameChunk has to be called several 1027 times to decode enough audio frames to please the caller of 1028 BMediaDecoder::Decode(). 1029 1030 This function assumes to be called only when the following assumptions 1031 hold true: 1032 1. fDecodedDataBufferSize equals zero. 1033 1034 After this function returns successfully the caller can safely make the 1035 following assumptions: 1036 1. fDecodedDataBufferSize is greater than zero. 1037 2. fDecodedDataBufferOffset is set to zero. 1038 3. fDecodedDataBuffer contains audio frames. 1039 1040 1041 \returns B_OK on successfully decoding one audio frame chunk. 1042 \returns B_LAST_BUFFER_ERROR No more audio frame chunks available. From 1043 this point on further calls will return this same error. 1044 \returns B_ERROR Decoding failed 1045 */ 1046 status_t 1047 AVCodecDecoder::_DecodeNextAudioFrameChunk() 1048 { 1049 assert(fDecodedDataBufferSize == 0); 1050 1051 while (fDecodedDataBufferSize == 0) { 1052 status_t loadingChunkStatus 1053 = _LoadNextChunkIfNeededAndAssignStartTime(); 1054 if (loadingChunkStatus != B_OK) 1055 return loadingChunkStatus; 1056 1057 status_t decodingStatus 1058 = _DecodeSomeAudioFramesIntoEmptyDecodedDataBuffer(); 1059 if (decodingStatus != B_OK) { 1060 // Assume the audio decoded until now is broken so replace it with 1061 // some silence. 1062 memset(fDecodedData, 0, fRawDecodedAudio->linesize[0]); 1063 1064 if (!fAudioDecodeError) { 1065 // Report failure if not done already 1066 int32 chunkBufferOffset = fTempPacket.data - fChunkBuffer; 1067 printf("########### audio decode error, " 1068 "fTempPacket.size %d, fChunkBuffer data offset %" B_PRId32 1069 "\n", fTempPacket.size, chunkBufferOffset); 1070 fAudioDecodeError = true; 1071 } 1072 1073 // Assume that next audio chunk can be decoded so keep decoding. 1074 continue; 1075 } 1076 1077 fAudioDecodeError = false; 1078 } 1079 1080 return B_OK; 1081 } 1082 1083 1084 /*! \brief Tries to decode at least one audio frame and store it in the 1085 fDecodedDataBuffer. 1086 1087 This function assumes to be called only when the following assumptions 1088 hold true: 1089 1. fDecodedDataBufferSize equals zero. 1090 2. fTempPacket.size is greater than zero. 1091 1092 After this function returns successfully the caller can safely make the 1093 following assumptions: 1094 1. fDecodedDataBufferSize is greater than zero in the common case. 1095 Also see "Note" below. 1096 2. fTempPacket was updated to exclude the data chunk that was consumed 1097 by avcodec_decode_audio4(). 1098 3. fDecodedDataBufferOffset is set to zero. 1099 1100 When this function failed to decode at least one audio frame due to a 1101 decoding error the caller can safely make the following assumptions: 1102 1. fDecodedDataBufferSize equals zero. 1103 2. fTempPacket.size equals zero. 1104 1105 Note: It is possible that there wasn't any audio frame decoded into 1106 fDecodedDataBuffer after calling this function. This is normal and can 1107 happen when there was either a decoding error or there is some decoding 1108 delay in FFMPEGs audio decoder. Another call to this method is totally 1109 safe and is even expected as long as the calling assumptions hold true. 1110 1111 \returns B_OK Decoding successful. fDecodedDataBuffer contains decoded 1112 audio frames only when fDecodedDataBufferSize is greater than zero. 1113 fDecodedDataBuffer is empty, when avcodec_decode_audio4() didn't return 1114 audio frames due to delayed decoding or incomplete audio frames. 1115 \returns B_ERROR Decoding failed thus fDecodedDataBuffer contains no audio 1116 frames. 1117 */ 1118 status_t 1119 AVCodecDecoder::_DecodeSomeAudioFramesIntoEmptyDecodedDataBuffer() 1120 { 1121 assert(fDecodedDataBufferSize == 0); 1122 1123 memset(fDecodedDataBuffer, 0, sizeof(AVFrame)); 1124 av_frame_unref(fDecodedDataBuffer); 1125 fDecodedDataBufferOffset = 0; 1126 int gotAudioFrame = 0; 1127 1128 int encodedDataSizeInBytes = avcodec_decode_audio4(fCodecContext, 1129 fDecodedDataBuffer, &gotAudioFrame, &fTempPacket); 1130 if (encodedDataSizeInBytes <= 0) { 1131 // Error or failure to produce decompressed output. 1132 // Skip the temp packet data entirely. 1133 fTempPacket.size = 0; 1134 return B_ERROR; 1135 } 1136 1137 fTempPacket.data += encodedDataSizeInBytes; 1138 fTempPacket.size -= encodedDataSizeInBytes; 1139 1140 bool gotNoAudioFrame = gotAudioFrame == 0; 1141 if (gotNoAudioFrame) 1142 return B_OK; 1143 1144 fDecodedDataBufferSize = fDecodedDataBuffer->nb_samples; 1145 if (fDecodedDataBufferSize < 0) 1146 fDecodedDataBufferSize = 0; 1147 1148 return B_OK; 1149 } 1150 1151 1152 /*! \brief Updates relevant fields of the class member fHeader with the 1153 properties of the most recently decoded audio frame. 1154 1155 The following fields of fHeader are updated: 1156 - fHeader.type 1157 - fHeader.file_pos 1158 - fHeader.orig_size 1159 - fHeader.start_time 1160 - fHeader.size_used 1161 - fHeader.u.raw_audio.frame_rate 1162 - fHeader.u.raw_audio.channel_count 1163 1164 It is assumed that this function is called only when the following asserts 1165 hold true: 1166 1. We actually got a new audio frame decoded by the audio decoder. 1167 2. fHeader wasn't updated for the new audio frame yet. You MUST call 1168 this method only once per decoded audio frame. 1169 3. fRawDecodedAudio's fields relate to the first audio frame contained 1170 in fDecodedData. Especially the following fields are of importance: 1171 - fRawDecodedAudio->pkt_dts: Start time of first audio frame 1172 - fRawDecodedAudio->opaque: Contains the following fields for 1173 the first audio frame: 1174 - channels: Channel count of first audio frame 1175 - sample_rate: Frame rate of first audio frame 1176 */ 1177 void 1178 AVCodecDecoder::_UpdateMediaHeaderForAudioFrame() 1179 { 1180 fHeader.type = B_MEDIA_RAW_AUDIO; 1181 fHeader.file_pos = 0; 1182 fHeader.orig_size = 0; 1183 fHeader.start_time = fRawDecodedAudio->pkt_dts; 1184 fHeader.size_used = fRawDecodedAudio->linesize[0]; 1185 1186 avformat_codec_context* codecContext 1187 = static_cast<avformat_codec_context*>(fRawDecodedAudio->opaque); 1188 fHeader.u.raw_audio.channel_count = codecContext->channels; 1189 fHeader.u.raw_audio.frame_rate = codecContext->sample_rate; 1190 } 1191 1192 1193 /*! \brief Decodes next video frame. 1194 1195 We decode exactly one video frame into fDecodedData. To achieve this goal, 1196 we might need to request several chunks of encoded data resulting in a 1197 variable execution time of this function. 1198 1199 The length of the decoded video frame is stored in 1200 fDecodedDataSizeInBytes. If this variable is greater than zero, you can 1201 assert that there is a valid video frame available in fDecodedData. 1202 1203 The decoded video frame in fDecodedData has color space conversion and 1204 deinterlacing already applied. 1205 1206 To every decoded video frame there is a media_header populated in 1207 fHeader, containing the corresponding video frame properties. 1208 1209 Normally every decoded video frame has a start_time field populated in the 1210 associated fHeader, that determines the presentation time of the frame. 1211 This relationship will only hold true, when each data chunk that is 1212 provided via GetNextChunk() contains data for exactly one encoded video 1213 frame (one complete frame) - not more and not less. 1214 1215 We can decode data chunks that contain partial video frame data, too. In 1216 that case, you cannot trust the value of the start_time field in fHeader. 1217 We simply have no logic in place to establish a meaningful relationship 1218 between an incomplete frame and the start time it should be presented. 1219 Though this might change in the future. 1220 1221 We can decode data chunks that contain more than one video frame, too. In 1222 that case, you cannot trust the value of the start_time field in fHeader. 1223 We simply have no logic in place to track the start_time across multiple 1224 video frames. So a meaningful relationship between the 2nd, 3rd, ... frame 1225 and the start time it should be presented isn't established at the moment. 1226 Though this might change in the future. 1227 1228 More over the fOutputFrameRate variable is updated for every decoded video 1229 frame. 1230 1231 On first call the member variables fSwsContext / fFormatConversionFunc are 1232 initialized. 1233 1234 \returns B_OK when we successfully decoded one video frame 1235 \returns B_LAST_BUFFER_ERROR when there are no more video frames available. 1236 \returns B_NO_MEMORY when we have no memory left for correct operation. 1237 \returns Other Errors 1238 */ 1239 status_t 1240 AVCodecDecoder::_DecodeNextVideoFrame() 1241 { 1242 int error; 1243 int send_error; 1244 1245 #if DO_PROFILING 1246 bigtime_t startTime = system_time(); 1247 #endif 1248 1249 error = avcodec_receive_frame(fCodecContext, fRawDecodedPicture); 1250 1251 if (error == AVERROR(EAGAIN)) { 1252 do { 1253 status_t loadingChunkStatus 1254 = _LoadNextChunkIfNeededAndAssignStartTime(); 1255 if (loadingChunkStatus == B_LAST_BUFFER_ERROR) 1256 return _FlushOneVideoFrameFromDecoderBuffer(); 1257 if (loadingChunkStatus != B_OK) { 1258 TRACE("[v] AVCodecDecoder::_DecodeNextVideoFrame(): error from " 1259 "GetNextChunk(): %s\n", strerror(loadingChunkStatus)); 1260 return loadingChunkStatus; 1261 } 1262 1263 char timestamp[AV_TS_MAX_STRING_SIZE]; 1264 av_ts_make_time_string(timestamp, 1265 fTempPacket.dts, &fCodecContext->time_base); 1266 TRACE("[v] Feed %d more bytes (dts %s)\n", fTempPacket.size, 1267 timestamp); 1268 1269 send_error = avcodec_send_packet(fCodecContext, &fTempPacket); 1270 if (send_error < 0 && send_error != AVERROR(EAGAIN)) { 1271 TRACE("[v] AVCodecDecoder: ignoring error in decoding frame " 1272 "%lld: %d\n", fFrame, error); 1273 } 1274 1275 // Packet is consumed, clear it 1276 fTempPacket.data = NULL; 1277 fTempPacket.size = 0; 1278 1279 error = avcodec_receive_frame(fCodecContext, fRawDecodedPicture); 1280 if (error != 0 && error != AVERROR(EAGAIN)) { 1281 TRACE("[v] frame %lld - decoding error, error code: %d, " 1282 "chunk size: %ld\n", fFrame, error, fChunkBufferSize); 1283 } 1284 1285 } while (error != 0); 1286 } 1287 1288 #if DO_PROFILING 1289 bigtime_t formatConversionStart = system_time(); 1290 #endif 1291 1292 status_t handleStatus = _HandleNewVideoFrameAndUpdateSystemState(); 1293 if (handleStatus != B_OK) 1294 return handleStatus; 1295 1296 #if DO_PROFILING 1297 bigtime_t doneTime = system_time(); 1298 decodingTime += formatConversionStart - startTime; 1299 conversionTime += doneTime - formatConversionStart; 1300 profileCounter++; 1301 if (!(fFrame % 5)) { 1302 printf("[v] profile: d1 = %lld, d2 = %lld (%lld) required %Ld\n", 1303 decodingTime / profileCounter, conversionTime / profileCounter, 1304 fFrame, bigtime_t(1000000LL / fOutputFrameRate)); 1305 decodingTime = 0; 1306 conversionTime = 0; 1307 profileCounter = 0; 1308 } 1309 #endif 1310 return error; 1311 } 1312 1313 1314 /*! \brief Applies all essential video input properties to fCodecContext that were 1315 passed to AVCodecDecoder when Setup() was called. 1316 1317 Note: This function must be called before the AVCodec is opened via 1318 avcodec_open2(). Otherwise the behaviour of FFMPEG's video decoding 1319 function avcodec_decode_video2() is undefined. 1320 1321 Essential properties applied from fInputFormat.u.encoded_video.output: 1322 - display.line_width copied to fCodecContext->width 1323 - display.line_count copied to fCodecContext->height 1324 - pixel_width_aspect and pixel_height_aspect converted to 1325 fCodecContext->sample_aspect_ratio 1326 - field_rate converted to fCodecContext->time_base and 1327 fCodecContext->ticks_per_frame 1328 1329 Other essential properties being applied: 1330 - fExtraData to fCodecContext->extradata 1331 - fExtraDataSize to fCodecContext->extradata_size 1332 */ 1333 void 1334 AVCodecDecoder::_ApplyEssentialVideoContainerPropertiesToContext() 1335 { 1336 media_raw_video_format containerProperties 1337 = fInputFormat.u.encoded_video.output; 1338 1339 fCodecContext->width = containerProperties.display.line_width; 1340 fCodecContext->height = containerProperties.display.line_count; 1341 1342 if (containerProperties.pixel_width_aspect > 0 1343 && containerProperties.pixel_height_aspect > 0) { 1344 ConvertVideoAspectWidthAndHeightToAVCodecContext( 1345 containerProperties.pixel_width_aspect, 1346 containerProperties.pixel_height_aspect, *fCodecContext); 1347 } 1348 1349 if (containerProperties.field_rate > 0.0) { 1350 ConvertVideoFrameRateToAVCodecContext(containerProperties.field_rate, 1351 *fCodecContext); 1352 } 1353 1354 fCodecContext->extradata = reinterpret_cast<uint8_t*>(fExtraData); 1355 fCodecContext->extradata_size = fExtraDataSize; 1356 } 1357 1358 1359 /*! \brief Loads the next chunk into fChunkBuffer and assigns it (including 1360 the start time) to fTempPacket but only if fTempPacket is empty. 1361 1362 \returns B_OK 1363 1. meaning: Next chunk is loaded. 1364 2. meaning: No need to load and assign anything. Proceed as usual. 1365 \returns B_LAST_BUFFER_ERROR No more chunks available. fChunkBuffer and 1366 fTempPacket are left untouched. 1367 \returns Other errors Caller should bail out because fChunkBuffer and 1368 fTempPacket are in unknown states. Normal operation cannot be 1369 guaranteed. 1370 */ 1371 status_t 1372 AVCodecDecoder::_LoadNextChunkIfNeededAndAssignStartTime() 1373 { 1374 if (fTempPacket.size > 0) 1375 return B_OK; 1376 1377 const void* chunkBuffer = NULL; 1378 size_t chunkBufferSize = 0; 1379 // In the case that GetNextChunk() returns an error fChunkBufferSize 1380 // should be left untouched. 1381 media_header chunkMediaHeader; 1382 1383 status_t getNextChunkStatus = GetNextChunk(&chunkBuffer, &chunkBufferSize, 1384 &chunkMediaHeader); 1385 if (getNextChunkStatus != B_OK) 1386 return getNextChunkStatus; 1387 1388 status_t chunkBufferPaddingStatus 1389 = _CopyChunkToChunkBufferAndAddPadding(chunkBuffer, chunkBufferSize); 1390 if (chunkBufferPaddingStatus != B_OK) 1391 return chunkBufferPaddingStatus; 1392 1393 fTempPacket.data = fChunkBuffer; 1394 fTempPacket.size = fChunkBufferSize; 1395 fTempPacket.dts = chunkMediaHeader.start_time; 1396 // Let FFMPEG handle the correct relationship between start_time and 1397 // decoded a/v frame. By doing so we are simply copying the way how it 1398 // is implemented in ffplay.c for video frames (for audio frames it 1399 // works, too, but isn't used by ffplay.c). 1400 // \see http://git.videolan.org/?p=ffmpeg.git;a=blob;f=ffplay.c;h=09623db374e5289ed20b7cc28c262c4375a8b2e4;hb=9153b33a742c4e2a85ff6230aea0e75f5a8b26c2#l1502 1401 // 1402 // FIXME: Research how to establish a meaningful relationship between 1403 // start_time and decoded a/v frame when the received chunk buffer 1404 // contains partial a/v frames. Maybe some data formats do contain time 1405 // stamps (ake pts / dts fields) that can be evaluated by FFMPEG. But 1406 // as long as I don't have such video data to test it, it makes no 1407 // sense trying to implement it. 1408 // 1409 // FIXME: Implement tracking start_time of video frames originating in 1410 // data chunks that encode more than one video frame at a time. In that 1411 // case on would increment the start_time for each consecutive frame of 1412 // such a data chunk (like it is done for audio frame decoding). But as 1413 // long as I don't have such video data to test it, it makes no sense 1414 // to implement it. 1415 1416 #ifdef LOG_STREAM_TO_FILE 1417 BFile* logFile = fIsAudio ? &sAudioStreamLogFile : &sVideoStreamLogFile; 1418 if (sDumpedPackets < 100) { 1419 logFile->Write(chunkBuffer, fChunkBufferSize); 1420 printf("wrote %ld bytes\n", fChunkBufferSize); 1421 sDumpedPackets++; 1422 } else if (sDumpedPackets == 100) 1423 logFile->Unset(); 1424 #endif 1425 1426 return B_OK; 1427 } 1428 1429 1430 /*! \brief Copies a chunk into fChunkBuffer and adds a "safety net" of 1431 additional memory as required by FFMPEG for input buffers to video 1432 decoders. 1433 1434 This is needed so that some decoders can read safely a predefined number of 1435 bytes at a time for performance optimization purposes. 1436 1437 The additional memory has a size of AV_INPUT_BUFFER_PADDING_SIZE as defined 1438 in avcodec.h. 1439 1440 Ownership of fChunkBuffer memory is with the class so it needs to be freed 1441 at the right times (on destruction, on seeking). 1442 1443 Also update fChunkBufferSize to reflect the size of the contained data 1444 (leaving out the padding). 1445 1446 \param chunk The chunk to copy. 1447 \param chunkSize Size of the chunk in bytes 1448 1449 \returns B_OK Padding was successful. You are responsible for releasing the 1450 allocated memory. fChunkBufferSize is set to chunkSize. 1451 \returns B_NO_MEMORY Padding failed. 1452 fChunkBuffer is set to NULL making it safe to call free() on it. 1453 fChunkBufferSize is set to 0 to reflect the size of fChunkBuffer. 1454 */ 1455 status_t 1456 AVCodecDecoder::_CopyChunkToChunkBufferAndAddPadding(const void* chunk, 1457 size_t chunkSize) 1458 { 1459 fChunkBuffer = static_cast<uint8_t*>(realloc(fChunkBuffer, 1460 chunkSize + AV_INPUT_BUFFER_PADDING_SIZE)); 1461 if (fChunkBuffer == NULL) { 1462 fChunkBufferSize = 0; 1463 return B_NO_MEMORY; 1464 } 1465 1466 memcpy(fChunkBuffer, chunk, chunkSize); 1467 memset(fChunkBuffer + chunkSize, 0, AV_INPUT_BUFFER_PADDING_SIZE); 1468 // Establish safety net, by zero'ing the padding area. 1469 1470 fChunkBufferSize = chunkSize; 1471 1472 return B_OK; 1473 } 1474 1475 1476 /*! \brief Executes all steps needed for a freshly decoded video frame. 1477 1478 \see _UpdateMediaHeaderForVideoFrame() and 1479 \see _DeinterlaceAndColorConvertVideoFrame() for when you are allowed to 1480 call this method. 1481 1482 \returns B_OK when video frame was handled successfully 1483 \returnb B_NO_MEMORY when no memory is left for correct operation. 1484 */ 1485 status_t 1486 AVCodecDecoder::_HandleNewVideoFrameAndUpdateSystemState() 1487 { 1488 _UpdateMediaHeaderForVideoFrame(); 1489 status_t postProcessStatus = _DeinterlaceAndColorConvertVideoFrame(); 1490 if (postProcessStatus != B_OK) 1491 return postProcessStatus; 1492 1493 ConvertAVCodecContextToVideoFrameRate(*fCodecContext, fOutputFrameRate); 1494 1495 #ifdef DEBUG 1496 dump_ffframe_video(fRawDecodedPicture, "ffpict"); 1497 #endif 1498 1499 fFrame++; 1500 1501 return B_OK; 1502 } 1503 1504 1505 /*! \brief Flushes one video frame - if any - still buffered by the decoder. 1506 1507 Some FFMPEG decoder are buffering video frames. To retrieve those buffered 1508 frames the decoder needs to be told so. 1509 1510 The intended use of this method is to call it, once there are no more data 1511 chunks for decoding left. Reframed in other words: Once GetNextChunk() 1512 returns with status B_LAST_BUFFER_ERROR it is time to start flushing. 1513 1514 \returns B_OK Retrieved one video frame, handled it accordingly and updated 1515 the system state accordingly. 1516 There maybe more video frames left. So it is valid for the client of 1517 AVCodecDecoder to call it one more time. 1518 1519 \returns B_LAST_BUFFER_ERROR No video frame left. 1520 The client of the AVCodecDecoder should stop calling it now. 1521 1522 \returns B_NO_MEMORY No memory left for correct operation. 1523 */ 1524 status_t 1525 AVCodecDecoder::_FlushOneVideoFrameFromDecoderBuffer() 1526 { 1527 // Tell the decoder there is nothing to send anymore 1528 avcodec_send_packet(fCodecContext, NULL); 1529 1530 // Get any remaining frame 1531 int error = avcodec_receive_frame(fCodecContext, fRawDecodedPicture); 1532 1533 if (error != 0 && error != AVERROR(EAGAIN)) { 1534 // video buffer is flushed successfully 1535 // (or there is an error, not much we can do about it) 1536 return B_LAST_BUFFER_ERROR; 1537 } 1538 1539 return _HandleNewVideoFrameAndUpdateSystemState(); 1540 } 1541 1542 1543 /*! \brief Updates relevant fields of the class member fHeader with the 1544 properties of the most recently decoded video frame. 1545 1546 It is assumed that this function is called only when the following asserts 1547 hold true: 1548 1. We actually got a new picture decoded by the video decoder. 1549 2. fHeader wasn't updated for the new picture yet. You MUST call this 1550 method only once per decoded video frame. 1551 3. This function MUST be called after 1552 _DeinterlaceAndColorConvertVideoFrame() as it relys on an updated 1553 fDecodedDataSizeInBytes. 1554 4. There will be at maximumn only one decoded video frame in our cache 1555 at any single point in time. Otherwise you couldn't tell to which 1556 cached decoded video frame the properties in fHeader relate to. 1557 5. AVCodecContext is still valid for this video frame (This is the case 1558 when this function is called after avcodec_decode_video2() and 1559 before the next call to avcodec_decode_video2(). 1560 */ 1561 void 1562 AVCodecDecoder::_UpdateMediaHeaderForVideoFrame() 1563 { 1564 fHeader.type = B_MEDIA_RAW_VIDEO; 1565 fHeader.file_pos = 0; 1566 fHeader.orig_size = 0; 1567 fHeader.start_time = fRawDecodedPicture->pkt_dts; 1568 // The pkt_dts is already in microseconds, even if ffmpeg docs says 1569 // 'in codec time_base units' 1570 fHeader.size_used = av_image_get_buffer_size( 1571 colorspace_to_pixfmt(fOutputColorSpace), fRawDecodedPicture->width, 1572 fRawDecodedPicture->height, 1); 1573 fHeader.u.raw_video.display_line_width = fRawDecodedPicture->width; 1574 fHeader.u.raw_video.display_line_count = fRawDecodedPicture->height; 1575 fHeader.u.raw_video.bytes_per_row 1576 = CalculateBytesPerRowWithColorSpaceAndVideoWidth(fOutputColorSpace, 1577 fRawDecodedPicture->width); 1578 fHeader.u.raw_video.field_gamma = 1.0; 1579 fHeader.u.raw_video.field_sequence = fFrame; 1580 fHeader.u.raw_video.field_number = 0; 1581 fHeader.u.raw_video.pulldown_number = 0; 1582 fHeader.u.raw_video.first_active_line = 1; 1583 fHeader.u.raw_video.line_count = fRawDecodedPicture->height; 1584 1585 ConvertAVCodecContextToVideoAspectWidthAndHeight(*fCodecContext, 1586 fHeader.u.raw_video.pixel_width_aspect, 1587 fHeader.u.raw_video.pixel_height_aspect); 1588 1589 char timestamp[AV_TS_MAX_STRING_SIZE]; 1590 av_ts_make_time_string(timestamp, 1591 fRawDecodedPicture->best_effort_timestamp, &fCodecContext->time_base); 1592 1593 TRACE("[v] start_time=%s field_sequence=%lu\n", 1594 timestamp, fHeader.u.raw_video.field_sequence); 1595 } 1596 1597 1598 /*! \brief This function applies deinterlacing (only if needed) and color 1599 conversion to the video frame in fRawDecodedPicture. 1600 1601 It is assumed that fRawDecodedPicture wasn't deinterlaced and color 1602 converted yet (otherwise this function behaves in unknown manners). 1603 1604 This function MUST be called after _UpdateMediaHeaderForVideoFrame() as it 1605 relys on the fHeader.size_used and fHeader.u.raw_video.bytes_per_row fields 1606 for correct operation 1607 1608 You should only call this function when you got a new picture decoded by 1609 the video decoder. 1610 1611 When this function finishes the postprocessed video frame will be available 1612 in fPostProcessedDecodedPicture and fDecodedData (fDecodedDataSizeInBytes 1613 will be set accordingly). 1614 1615 \returns B_OK video frame successfully deinterlaced and color converted. 1616 \returns B_NO_MEMORY Not enough memory available for correct operation. 1617 */ 1618 status_t 1619 AVCodecDecoder::_DeinterlaceAndColorConvertVideoFrame() 1620 { 1621 int displayWidth = fRawDecodedPicture->width; 1622 int displayHeight = fRawDecodedPicture->height; 1623 AVFrame deinterlacedPicture; 1624 bool useDeinterlacedPicture = false; 1625 1626 if (fRawDecodedPicture->interlaced_frame) { 1627 AVFrame rawPicture; 1628 rawPicture.data[0] = fRawDecodedPicture->data[0]; 1629 rawPicture.data[1] = fRawDecodedPicture->data[1]; 1630 rawPicture.data[2] = fRawDecodedPicture->data[2]; 1631 rawPicture.data[3] = fRawDecodedPicture->data[3]; 1632 rawPicture.linesize[0] = fRawDecodedPicture->linesize[0]; 1633 rawPicture.linesize[1] = fRawDecodedPicture->linesize[1]; 1634 rawPicture.linesize[2] = fRawDecodedPicture->linesize[2]; 1635 rawPicture.linesize[3] = fRawDecodedPicture->linesize[3]; 1636 1637 if (av_image_alloc(deinterlacedPicture.data, 1638 deinterlacedPicture.linesize, displayWidth, displayHeight, 1639 fCodecContext->pix_fmt, 1) < 0) 1640 return B_NO_MEMORY; 1641 1642 // deinterlace implemented using avfilter 1643 _ProcessFilterGraph(&deinterlacedPicture, &rawPicture, 1644 fCodecContext->pix_fmt, displayWidth, displayHeight); 1645 useDeinterlacedPicture = true; 1646 } 1647 1648 // Some decoders do not set pix_fmt until they have decoded 1 frame 1649 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION 1650 if (fSwsContext == NULL) { 1651 fSwsContext = sws_getContext(displayWidth, displayHeight, 1652 fCodecContext->pix_fmt, displayWidth, displayHeight, 1653 colorspace_to_pixfmt(fOutputColorSpace), 1654 SWS_FAST_BILINEAR, NULL, NULL, NULL); 1655 } 1656 #else 1657 if (fFormatConversionFunc == NULL) { 1658 fFormatConversionFunc = resolve_colorspace(fOutputColorSpace, 1659 fCodecContext->pix_fmt, displayWidth, displayHeight); 1660 } 1661 #endif 1662 1663 fDecodedDataSizeInBytes = fHeader.size_used; 1664 1665 if (fDecodedData == NULL) { 1666 const size_t kOptimalAlignmentForColorConversion = 32; 1667 posix_memalign(reinterpret_cast<void**>(&fDecodedData), 1668 kOptimalAlignmentForColorConversion, fDecodedDataSizeInBytes); 1669 } 1670 if (fDecodedData == NULL) 1671 return B_NO_MEMORY; 1672 1673 fPostProcessedDecodedPicture->data[0] = fDecodedData; 1674 fPostProcessedDecodedPicture->linesize[0] 1675 = fHeader.u.raw_video.bytes_per_row; 1676 1677 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION 1678 if (fSwsContext != NULL) { 1679 #else 1680 if (fFormatConversionFunc != NULL) { 1681 #endif 1682 if (useDeinterlacedPicture) { 1683 AVFrame deinterlacedFrame; 1684 deinterlacedFrame.data[0] = deinterlacedPicture.data[0]; 1685 deinterlacedFrame.data[1] = deinterlacedPicture.data[1]; 1686 deinterlacedFrame.data[2] = deinterlacedPicture.data[2]; 1687 deinterlacedFrame.data[3] = deinterlacedPicture.data[3]; 1688 deinterlacedFrame.linesize[0] 1689 = deinterlacedPicture.linesize[0]; 1690 deinterlacedFrame.linesize[1] 1691 = deinterlacedPicture.linesize[1]; 1692 deinterlacedFrame.linesize[2] 1693 = deinterlacedPicture.linesize[2]; 1694 deinterlacedFrame.linesize[3] 1695 = deinterlacedPicture.linesize[3]; 1696 1697 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION 1698 sws_scale(fSwsContext, deinterlacedFrame.data, 1699 deinterlacedFrame.linesize, 0, displayHeight, 1700 fPostProcessedDecodedPicture->data, 1701 fPostProcessedDecodedPicture->linesize); 1702 #else 1703 (*fFormatConversionFunc)(&deinterlacedFrame, 1704 fPostProcessedDecodedPicture, displayWidth, displayHeight); 1705 #endif 1706 } else { 1707 #if USE_SWS_FOR_COLOR_SPACE_CONVERSION 1708 sws_scale(fSwsContext, fRawDecodedPicture->data, 1709 fRawDecodedPicture->linesize, 0, displayHeight, 1710 fPostProcessedDecodedPicture->data, 1711 fPostProcessedDecodedPicture->linesize); 1712 #else 1713 (*fFormatConversionFunc)(fRawDecodedPicture, 1714 fPostProcessedDecodedPicture, displayWidth, displayHeight); 1715 #endif 1716 } 1717 } 1718 1719 if (fRawDecodedPicture->interlaced_frame) 1720 av_freep(&deinterlacedPicture.data[0]); 1721 1722 return B_OK; 1723 } 1724 1725 1726 /*! \brief Init the deinterlace filter graph. 1727 1728 \returns B_OK the filter graph could be built. 1729 \returns B_BAD_VALUE something was wrong with building the graph. 1730 */ 1731 status_t 1732 AVCodecDecoder::_InitFilterGraph(enum AVPixelFormat pixfmt, int32 width, 1733 int32 height) 1734 { 1735 if (fFilterGraph != NULL) { 1736 av_frame_free(&fFilterFrame); 1737 avfilter_graph_free(&fFilterGraph); 1738 } 1739 1740 fFilterGraph = avfilter_graph_alloc(); 1741 1742 BString arguments; 1743 arguments.SetToFormat("buffer=video_size=%" B_PRId32 "x%" B_PRId32 1744 ":pix_fmt=%d:time_base=1/1:pixel_aspect=0/1[in];[in]yadif[out];" 1745 "[out]buffersink", width, height, 1746 pixfmt); 1747 AVFilterInOut* inputs = NULL; 1748 AVFilterInOut* outputs = NULL; 1749 TRACE("[v] _InitFilterGraph(): %s\n", arguments.String()); 1750 int ret = avfilter_graph_parse2(fFilterGraph, arguments.String(), &inputs, 1751 &outputs); 1752 if (ret < 0) { 1753 fprintf(stderr, "avfilter_graph_parse2() failed\n"); 1754 return B_BAD_VALUE; 1755 } 1756 1757 ret = avfilter_graph_config(fFilterGraph, NULL); 1758 if (ret < 0) { 1759 fprintf(stderr, "avfilter_graph_config() failed\n"); 1760 return B_BAD_VALUE; 1761 } 1762 1763 fBufferSourceContext = avfilter_graph_get_filter(fFilterGraph, 1764 "Parsed_buffer_0"); 1765 fBufferSinkContext = avfilter_graph_get_filter(fFilterGraph, 1766 "Parsed_buffersink_2"); 1767 if (fBufferSourceContext == NULL || fBufferSinkContext == NULL) { 1768 fprintf(stderr, "avfilter_graph_get_filter() failed\n"); 1769 return B_BAD_VALUE; 1770 } 1771 fFilterFrame = av_frame_alloc(); 1772 fLastWidth = width; 1773 fLastHeight = height; 1774 fLastPixfmt = pixfmt; 1775 1776 return B_OK; 1777 } 1778 1779 1780 /*! \brief Process an AVPicture with the deinterlace filter graph. 1781 1782 We decode exactly one video frame into dst. 1783 Equivalent function for avpicture_deinterlace() from version 2.x. 1784 1785 \returns B_OK video frame successfully deinterlaced. 1786 \returns B_BAD_DATA No frame could be output. 1787 \returns B_NO_MEMORY Not enough memory available for correct operation. 1788 */ 1789 status_t 1790 AVCodecDecoder::_ProcessFilterGraph(AVFrame *dst, const AVFrame *src, 1791 enum AVPixelFormat pixfmt, int32 width, int32 height) 1792 { 1793 if (fFilterGraph == NULL || width != fLastWidth 1794 || height != fLastHeight || pixfmt != fLastPixfmt) { 1795 1796 status_t err = _InitFilterGraph(pixfmt, width, height); 1797 if (err != B_OK) 1798 return err; 1799 } 1800 1801 memcpy(fFilterFrame->data, src->data, sizeof(src->data)); 1802 memcpy(fFilterFrame->linesize, src->linesize, sizeof(src->linesize)); 1803 fFilterFrame->width = width; 1804 fFilterFrame->height = height; 1805 fFilterFrame->format = pixfmt; 1806 1807 int ret = av_buffersrc_add_frame(fBufferSourceContext, fFilterFrame); 1808 if (ret < 0) 1809 return B_NO_MEMORY; 1810 1811 ret = av_buffersink_get_frame(fBufferSinkContext, fFilterFrame); 1812 if (ret < 0) 1813 return B_BAD_DATA; 1814 1815 av_image_copy(dst->data, dst->linesize, (const uint8**)fFilterFrame->data, 1816 fFilterFrame->linesize, pixfmt, width, height); 1817 av_frame_unref(fFilterFrame); 1818 return B_OK; 1819 } 1820