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