1 /* 2 * Copyright 2009, Stephan Aßmus <superstippi@gmx.de> 3 * All rights reserved. Distributed under the terms of the GNU L-GPL license. 4 */ 5 6 #include "AVFormatReader.h" 7 8 #include <stdio.h> 9 #include <string.h> 10 #include <stdlib.h> 11 12 #include <new> 13 14 #include <AutoDeleter.h> 15 #include <Autolock.h> 16 #include <ByteOrder.h> 17 #include <DataIO.h> 18 #include <MediaDefs.h> 19 #include <MediaFormats.h> 20 21 extern "C" { 22 #include "avformat.h" 23 } 24 25 #include "DemuxerTable.h" 26 #include "gfx_util.h" 27 28 29 #define TRACE_AVFORMAT_READER 30 #ifdef TRACE_AVFORMAT_READER 31 # define TRACE printf 32 # define TRACE_IO(a...) 33 # define TRACE_SEEK(a...) 34 # define TRACE_PACKET(a...) 35 #else 36 # define TRACE(a...) 37 # define TRACE_IO(a...) 38 # define TRACE_SEEK(a...) 39 # define TRACE_PACKET(a...) 40 #endif 41 42 #define ERROR(a...) fprintf(stderr, a) 43 44 45 static const size_t kIOBufferSize = 64 * 1024; 46 // TODO: This could depend on the BMediaFile creation flags, IIRC, 47 // they allow to specify a buffering mode. 48 49 uint32 50 avformat_to_beos_format(SampleFormat format) 51 { 52 switch (format) { 53 case SAMPLE_FMT_U8: return media_raw_audio_format::B_AUDIO_UCHAR; 54 case SAMPLE_FMT_S16: return media_raw_audio_format::B_AUDIO_SHORT; 55 case SAMPLE_FMT_S32: return media_raw_audio_format::B_AUDIO_INT; 56 case SAMPLE_FMT_FLT: return media_raw_audio_format::B_AUDIO_FLOAT; 57 case SAMPLE_FMT_DBL: return media_raw_audio_format::B_AUDIO_DOUBLE; 58 default: 59 break; 60 } 61 return 0; 62 } 63 64 65 // #pragma mark - AVFormatReader::StreamCookie 66 67 68 class AVFormatReader::StreamCookie { 69 public: 70 StreamCookie(BPositionIO* source, 71 BLocker* streamLock); 72 virtual ~StreamCookie(); 73 74 // Init an indivual AVFormatContext 75 status_t Open(); 76 77 // Setup this stream to point to the AVStream at the given streamIndex. 78 // This will also initialize the media_format. 79 status_t Init(int32 streamIndex); 80 81 inline const AVFormatContext* Context() const 82 { return fContext; } 83 int32 Index() const; 84 int32 CountStreams() const; 85 int32 StreamIndexFor(int32 virtualIndex) const; 86 inline int32 VirtualIndex() const 87 { return fVirtualIndex; } 88 89 inline const media_format& Format() const 90 { return fFormat; } 91 92 double FrameRate() const; 93 94 // Support for AVFormatReader 95 status_t GetStreamInfo(int64* frameCount, 96 bigtime_t* duration, media_format* format, 97 const void** infoBuffer, 98 size_t* infoSize) const; 99 100 status_t Seek(uint32 flags, int64* frame, 101 bigtime_t* time); 102 status_t FindKeyFrame(uint32 flags, int64* frame, 103 bigtime_t* time) const; 104 105 status_t GetNextChunk(const void** chunkBuffer, 106 size_t* chunkSize, 107 media_header* mediaHeader); 108 109 private: 110 // I/O hooks for libavformat, cookie will be a StreamCookie instance. 111 // Since multiple StreamCookies use the same BPositionIO source, they 112 // maintain the position individually, and may need to seek the source 113 // if it does not match anymore in _Read(). 114 // TODO: This concept prevents the use of a plain BDataIO that is not 115 // seekable. There is a version of AVFormatReader in the SVN history 116 // which implements packet buffering for other streams when reading 117 // packets. To support non-seekable network streams for example, this 118 // code should be resurrected. It will make handling seekable streams, 119 // especially from different threads that read from totally independent 120 // positions in the stream (aggressive pre-buffering perhaps), a lot 121 // more difficult with potentially large memory overhead. 122 static int _Read(void* cookie, uint8* buffer, 123 int bufferSize); 124 static off_t _Seek(void* cookie, off_t offset, int whence); 125 126 status_t _NextPacket(bool reuse); 127 128 private: 129 BPositionIO* fSource; 130 off_t fPosition; 131 // Since different threads may read from the source, 132 // we need to protect the file position and I/O by a lock. 133 BLocker* fStreamLock; 134 135 AVFormatContext* fContext; 136 AVStream* fStream; 137 int32 fVirtualIndex; 138 139 ByteIOContext fIOContext; 140 uint8 fIOBuffer[kIOBufferSize]; 141 142 AVPacket fPacket; 143 bool fReusePacket; 144 145 media_format fFormat; 146 }; 147 148 149 150 AVFormatReader::StreamCookie::StreamCookie(BPositionIO* source, 151 BLocker* streamLock) 152 : 153 fSource(source), 154 fPosition(0), 155 fStreamLock(streamLock), 156 157 fContext(NULL), 158 fStream(NULL), 159 fVirtualIndex(-1), 160 161 fReusePacket(false) 162 { 163 memset(&fIOBuffer, 0, sizeof(fIOBuffer)); 164 memset(&fFormat, 0, sizeof(media_format)); 165 av_new_packet(&fPacket, 0); 166 } 167 168 169 AVFormatReader::StreamCookie::~StreamCookie() 170 { 171 av_free_packet(&fPacket); 172 av_free(fContext); 173 } 174 175 176 status_t 177 AVFormatReader::StreamCookie::Open() 178 { 179 // Init probing data 180 size_t probeSize = 2048; 181 AVProbeData probeData; 182 probeData.filename = ""; 183 probeData.buf = fIOBuffer; 184 probeData.buf_size = probeSize; 185 186 // Read a bit of the input... 187 // NOTE: Even if other streams have already read from the source, 188 // it is ok to not seek first, since our fPosition is 0, so the necessary 189 // seek will happen automatically in _Read(). 190 if (_Read(this, fIOBuffer, probeSize) != (ssize_t)probeSize) 191 return B_IO_ERROR; 192 // ...and seek back to the beginning of the file. This is important 193 // since libavformat will assume the stream to be at offset 0, the 194 // probe data is not reused. 195 _Seek(this, 0, SEEK_SET); 196 197 // Probe the input format 198 AVInputFormat* inputFormat = av_probe_input_format(&probeData, 1); 199 200 if (inputFormat == NULL) { 201 TRACE("AVFormatReader::StreamCookie::Open() - " 202 "av_probe_input_format() failed!\n"); 203 return B_NOT_SUPPORTED; 204 } 205 206 TRACE("AVFormatReader::StreamCookie::Open() - " 207 "av_probe_input_format(): %s\n", inputFormat->name); 208 209 const DemuxerFormat* demuxerFormat = demuxer_format_for(inputFormat); 210 if (demuxerFormat == NULL) { 211 // We could support this format, but we don't want to. Bail out. 212 ERROR("AVFormatReader::StreamCookie::Open() - " 213 "support for demuxer '%s' is not enabled. " 214 "See DemuxerTable.cpp\n", inputFormat->name); 215 return B_NOT_SUPPORTED; 216 } 217 218 // Init I/O context with buffer and hook functions, pass ourself as 219 // cookie. 220 if (init_put_byte(&fIOContext, fIOBuffer, kIOBufferSize, 0, this, 221 _Read, 0, _Seek) != 0) { 222 TRACE("AVFormatReader::StreamCookie::Open() - " 223 "init_put_byte() failed!\n"); 224 return B_ERROR; 225 } 226 227 // Initialize our context. 228 if (av_open_input_stream(&fContext, &fIOContext, "", inputFormat, 229 NULL) < 0) { 230 TRACE("AVFormatReader::StreamCookie::Open() - " 231 "av_open_input_stream() failed!\n"); 232 return B_NOT_SUPPORTED; 233 } 234 235 // Retrieve stream information 236 if (av_find_stream_info(fContext) < 0) { 237 TRACE("AVFormatReader::StreamCookie::Open() - " 238 "av_find_stream_info() failed!\n"); 239 return B_NOT_SUPPORTED; 240 } 241 242 TRACE("AVFormatReader::StreamCookie::Open() - " 243 "av_find_stream_info() success!\n"); 244 245 return B_OK; 246 } 247 248 249 status_t 250 AVFormatReader::StreamCookie::Init(int32 virtualIndex) 251 { 252 TRACE("AVFormatReader::StreamCookie::Init(%ld)\n", virtualIndex); 253 254 if (fContext == NULL) 255 return B_NO_INIT; 256 257 int32 streamIndex = StreamIndexFor(virtualIndex); 258 if (streamIndex < 0) { 259 TRACE(" Bad stream index!\n"); 260 return B_BAD_INDEX; 261 } 262 263 TRACE(" context stream index: %ld\n", streamIndex); 264 265 const DemuxerFormat* demuxerFormat = demuxer_format_for(fContext->iformat); 266 if (demuxerFormat == NULL) { 267 TRACE(" unknown AVInputFormat!\n"); 268 return B_NOT_SUPPORTED; 269 } 270 271 // We need to remember the virtual index so that 272 // AVFormatReader::FreeCookie() can clear the correct stream entry. 273 fVirtualIndex = virtualIndex; 274 275 // Make us point to the AVStream at streamIndex 276 fStream = fContext->streams[streamIndex]; 277 278 // Discard all other streams 279 for (unsigned i = 0; i < fContext->nb_streams; i++) { 280 if (i != (unsigned)streamIndex) 281 fContext->streams[i]->discard = AVDISCARD_ALL; 282 } 283 284 // Get a pointer to the AVCodecContext for the stream at streamIndex. 285 AVCodecContext* codecContext = fStream->codec; 286 AVStream* stream = fStream; 287 288 // initialize the media_format for this stream 289 media_format* format = &fFormat; 290 memset(format, 0, sizeof(media_format)); 291 292 media_format_description description; 293 294 // Set format family and type depending on codec_type of the stream. 295 switch (codecContext->codec_type) { 296 case CODEC_TYPE_AUDIO: 297 if ((codecContext->codec_id >= CODEC_ID_PCM_S16LE) 298 && (codecContext->codec_id <= CODEC_ID_PCM_U8)) { 299 TRACE(" raw audio\n"); 300 format->type = B_MEDIA_RAW_AUDIO; 301 description.family = B_ANY_FORMAT_FAMILY; 302 } else { 303 TRACE(" encoded audio\n"); 304 format->type = B_MEDIA_ENCODED_AUDIO; 305 description.family = demuxerFormat->audio_family; 306 } 307 break; 308 case CODEC_TYPE_VIDEO: 309 TRACE(" encoded video\n"); 310 format->type = B_MEDIA_ENCODED_VIDEO; 311 description.family = demuxerFormat->video_family; 312 break; 313 default: 314 TRACE(" unknown type\n"); 315 format->type = B_MEDIA_UNKNOWN_TYPE; 316 break; 317 } 318 319 if (format->type == B_MEDIA_RAW_AUDIO) { 320 switch (codecContext->codec_id) { 321 case CODEC_ID_PCM_S16LE: 322 format->u.raw_audio.format 323 = media_raw_audio_format::B_AUDIO_SHORT; 324 format->u.raw_audio.byte_order 325 = B_MEDIA_LITTLE_ENDIAN; 326 break; 327 case CODEC_ID_PCM_S16BE: 328 format->u.raw_audio.format 329 = media_raw_audio_format::B_AUDIO_SHORT; 330 format->u.raw_audio.byte_order 331 = B_MEDIA_BIG_ENDIAN; 332 break; 333 case CODEC_ID_PCM_U16LE: 334 // format->u.raw_audio.format 335 // = media_raw_audio_format::B_AUDIO_USHORT; 336 // format->u.raw_audio.byte_order 337 // = B_MEDIA_LITTLE_ENDIAN; 338 return B_NOT_SUPPORTED; 339 break; 340 case CODEC_ID_PCM_U16BE: 341 // format->u.raw_audio.format 342 // = media_raw_audio_format::B_AUDIO_USHORT; 343 // format->u.raw_audio.byte_order 344 // = B_MEDIA_BIG_ENDIAN; 345 return B_NOT_SUPPORTED; 346 break; 347 case CODEC_ID_PCM_S8: 348 format->u.raw_audio.format 349 = media_raw_audio_format::B_AUDIO_CHAR; 350 break; 351 case CODEC_ID_PCM_U8: 352 format->u.raw_audio.format 353 = media_raw_audio_format::B_AUDIO_UCHAR; 354 break; 355 default: 356 return B_NOT_SUPPORTED; 357 break; 358 } 359 } else { 360 uint32 codecTag = codecContext->codec_tag; 361 if (codecTag == 0) { 362 // Ugh, no codec_tag. Let's try to fake some known codecs. 363 // Such a situation seems to occur for the "mpegts" demuxer for 364 // example. These are some tags I could test with. 365 switch (codecContext->codec_id) { 366 case CODEC_ID_H264: 367 codecTag = 'h264'; 368 break; 369 case CODEC_ID_DVVIDEO: 370 codecTag = 'pcvd'; 371 break; 372 case CODEC_ID_AC3: 373 description.family = B_WAV_FORMAT_FAMILY; 374 codecTag = 0x2000; 375 break; 376 case CODEC_ID_FLAC: 377 description.family = B_WAV_FORMAT_FAMILY; 378 codecTag = 'flac'; 379 break; 380 case CODEC_ID_VP6F: 381 description.family = B_QUICKTIME_FORMAT_FAMILY; 382 codecTag = B_BENDIAN_TO_HOST_INT32('VP6F'); 383 break; 384 case CODEC_ID_MP3: 385 description.family = B_QUICKTIME_FORMAT_FAMILY; 386 codecTag = B_BENDIAN_TO_HOST_INT32('.mp3'); 387 break; 388 default: 389 fprintf(stderr, "ffmpeg codecTag is null, codec_id " 390 "unknown 0x%x\n", codecContext->codec_id); 391 // TODO: Add more... 392 break; 393 } 394 } 395 switch (description.family) { 396 case B_AIFF_FORMAT_FAMILY: 397 TRACE(" B_AIFF_FORMAT_FAMILY\n"); 398 description.u.aiff.codec = codecTag; 399 break; 400 case B_ASF_FORMAT_FAMILY: 401 TRACE(" B_ASF_FORMAT_FAMILY\n"); 402 // description.u.asf.guid = GUID(codecTag); 403 return B_NOT_SUPPORTED; 404 break; 405 case B_AVI_FORMAT_FAMILY: 406 TRACE(" B_AVI_FORMAT_FAMILY\n"); 407 description.u.avi.codec = codecTag; 408 break; 409 case B_AVR_FORMAT_FAMILY: 410 TRACE(" B_AVR_FORMAT_FAMILY\n"); 411 description.u.avr.id = codecTag; 412 break; 413 case B_MPEG_FORMAT_FAMILY: 414 TRACE(" B_MPEG_FORMAT_FAMILY\n"); 415 if (codecContext->codec_id == CODEC_ID_MPEG1VIDEO) 416 description.u.mpeg.id = B_MPEG_1_VIDEO; 417 else if (codecContext->codec_id == CODEC_ID_MPEG2VIDEO) 418 description.u.mpeg.id = B_MPEG_2_VIDEO; 419 else if (codecContext->codec_id == CODEC_ID_MP2) 420 description.u.mpeg.id = B_MPEG_2_AUDIO_LAYER_2; 421 else if (codecContext->codec_id == CODEC_ID_MP3) 422 description.u.mpeg.id = B_MPEG_1_AUDIO_LAYER_3; 423 // TODO: Add some more... 424 else 425 description.u.mpeg.id = B_MPEG_ANY; 426 break; 427 case B_QUICKTIME_FORMAT_FAMILY: 428 TRACE(" B_QUICKTIME_FORMAT_FAMILY\n"); 429 description.u.quicktime.codec 430 = B_HOST_TO_BENDIAN_INT32(codecTag); 431 break; 432 case B_WAV_FORMAT_FAMILY: 433 TRACE(" B_WAV_FORMAT_FAMILY\n"); 434 description.u.wav.codec = codecTag; 435 break; 436 case B_MISC_FORMAT_FAMILY: 437 TRACE(" B_MISC_FORMAT_FAMILY\n"); 438 description.u.misc.codec = codecTag; 439 break; 440 441 default: 442 break; 443 } 444 TRACE(" codecTag '%.4s' or %ld\n", (char*)&codecTag, codecTag); 445 TRACE(" fourcc '%.4s'\n", (char*)&codecContext->codec_id); 446 447 BMediaFormats formats; 448 status_t status = formats.GetFormatFor(description, format); 449 if (status < B_OK) 450 TRACE(" formats.GetFormatFor() error: %s\n", strerror(status)); 451 452 format->user_data_type = B_CODEC_TYPE_INFO; 453 *(uint32*)format->user_data = codecTag; 454 format->user_data[4] = 0; 455 } 456 457 // format->require_flags = 0; 458 format->deny_flags = B_MEDIA_MAUI_UNDEFINED_FLAGS; 459 460 switch (format->type) { 461 case B_MEDIA_RAW_AUDIO: 462 format->u.raw_audio.frame_rate = (float)codecContext->sample_rate; 463 format->u.raw_audio.channel_count = codecContext->channels; 464 format->u.encoded_audio.output.format 465 = avformat_to_beos_format(codecContext->sample_fmt); 466 format->u.raw_audio.buffer_size = 0; 467 468 // Read one packet and mark it for later re-use. (So our first 469 // GetNextChunk() call does not read another packet.) 470 if (_NextPacket(true) == B_OK) { 471 TRACE(" successfully determined audio buffer size: %d\n", 472 fPacket.size); 473 format->u.raw_audio.buffer_size = fPacket.size; 474 } 475 break; 476 477 case B_MEDIA_ENCODED_AUDIO: 478 format->u.encoded_audio.bit_rate = codecContext->bit_rate; 479 format->u.encoded_audio.frame_size = codecContext->frame_size; 480 // Fill in some info about possible output format 481 format->u.encoded_audio.output 482 = media_multi_audio_format::wildcard; 483 format->u.encoded_audio.output.frame_rate 484 = (float)codecContext->sample_rate; 485 format->u.encoded_audio.output.channel_count 486 = codecContext->channels; 487 format->u.encoded_audio.output.format 488 = avformat_to_beos_format(codecContext->sample_fmt); 489 break; 490 491 case B_MEDIA_ENCODED_VIDEO: 492 // TODO: Specifying any of these seems to throw off the format matching 493 // later on. 494 // format->u.encoded_video.avg_bit_rate = codecContext->bit_rate; 495 // format->u.encoded_video.max_bit_rate = codecContext->bit_rate 496 // + codecContext->bit_rate_tolerance; 497 498 // format->u.encoded_video.encoding 499 // = media_encoded_video_format::B_ANY; 500 501 // format->u.encoded_video.frame_size = 1; 502 // format->u.encoded_video.forward_history = 0; 503 // format->u.encoded_video.backward_history = 0; 504 505 // TODO: Fix up for interlaced video 506 format->u.encoded_video.output.field_rate 507 = av_q2d(stream->r_frame_rate); 508 if (format->u.encoded_video.output.field_rate == 50.0f) 509 format->u.encoded_video.output.field_rate = 25.0f; 510 format->u.encoded_video.output.interlace = 1; 511 512 format->u.encoded_video.output.first_active = 0; 513 format->u.encoded_video.output.last_active 514 = codecContext->height - 1; 515 // TODO: Maybe libavformat actually provides that info 516 // somewhere... 517 format->u.encoded_video.output.orientation 518 = B_VIDEO_TOP_LEFT_RIGHT; 519 520 // Calculate the display aspect ratio 521 AVRational displayAspectRatio; 522 if (codecContext->sample_aspect_ratio.num != 0) { 523 av_reduce(&displayAspectRatio.num, &displayAspectRatio.den, 524 codecContext->width 525 * codecContext->sample_aspect_ratio.num, 526 codecContext->height 527 * codecContext->sample_aspect_ratio.den, 528 1024 * 1024); 529 TRACE(" pixel aspect ratio: %d/%d, " 530 "display aspect ratio: %d/%d\n", 531 codecContext->sample_aspect_ratio.num, 532 codecContext->sample_aspect_ratio.den, 533 displayAspectRatio.num, displayAspectRatio.den); 534 } else { 535 av_reduce(&displayAspectRatio.num, &displayAspectRatio.den, 536 codecContext->width, codecContext->height, 1024 * 1024); 537 TRACE(" no display aspect ratio (%d/%d)\n", 538 displayAspectRatio.num, displayAspectRatio.den); 539 } 540 format->u.encoded_video.output.pixel_width_aspect 541 = displayAspectRatio.num; 542 format->u.encoded_video.output.pixel_height_aspect 543 = displayAspectRatio.den; 544 545 format->u.encoded_video.output.display.format 546 = pixfmt_to_colorspace(codecContext->pix_fmt); 547 format->u.encoded_video.output.display.line_width 548 = codecContext->width; 549 format->u.encoded_video.output.display.line_count 550 = codecContext->height; 551 format->u.encoded_video.output.display.bytes_per_row = 0; 552 format->u.encoded_video.output.display.pixel_offset = 0; 553 format->u.encoded_video.output.display.line_offset = 0; 554 format->u.encoded_video.output.display.flags = 0; // TODO 555 556 break; 557 558 default: 559 // This is an unknown format to us. 560 break; 561 } 562 563 // Add the meta data, if any 564 if (codecContext->extradata_size > 0) { 565 format->SetMetaData(codecContext->extradata, 566 codecContext->extradata_size); 567 TRACE(" extradata: %p\n", format->MetaData()); 568 } 569 570 TRACE(" extradata_size: %d\n", codecContext->extradata_size); 571 TRACE(" intra_matrix: %p\n", codecContext->intra_matrix); 572 TRACE(" inter_matrix: %p\n", codecContext->inter_matrix); 573 TRACE(" get_buffer(): %p\n", codecContext->get_buffer); 574 TRACE(" release_buffer(): %p\n", codecContext->release_buffer); 575 576 #ifdef TRACE_AVFORMAT_READER 577 char formatString[512]; 578 if (string_for_format(*format, formatString, sizeof(formatString))) 579 TRACE(" format: %s\n", formatString); 580 581 uint32 encoding = format->Encoding(); 582 TRACE(" encoding '%.4s'\n", (char*)&encoding); 583 #endif 584 585 return B_OK; 586 } 587 588 589 int32 590 AVFormatReader::StreamCookie::Index() const 591 { 592 if (fStream != NULL) 593 return fStream->index; 594 return -1; 595 } 596 597 598 int32 599 AVFormatReader::StreamCookie::CountStreams() const 600 { 601 // Figure out the stream count. If the context has "AVPrograms", use 602 // the first program (for now). 603 // TODO: To support "programs" properly, the BMediaFile/Track API should 604 // be extended accordingly. I guess programs are like TV channels in the 605 // same satilite transport stream. Maybe call them "TrackGroups". 606 if (fContext->nb_programs > 0) { 607 // See libavformat/utils.c:dump_format() 608 return fContext->programs[0]->nb_stream_indexes; 609 } 610 return fContext->nb_streams; 611 } 612 613 614 int32 615 AVFormatReader::StreamCookie::StreamIndexFor(int32 virtualIndex) const 616 { 617 // NOTE: See CountStreams() 618 if (fContext->nb_programs > 0) { 619 const AVProgram* program = fContext->programs[0]; 620 if (virtualIndex >= 0 621 && virtualIndex < (int32)program->nb_stream_indexes) { 622 return program->stream_index[virtualIndex]; 623 } 624 } else { 625 if (virtualIndex >= 0 && virtualIndex < (int32)fContext->nb_streams) 626 return virtualIndex; 627 } 628 return -1; 629 } 630 631 632 double 633 AVFormatReader::StreamCookie::FrameRate() const 634 { 635 // TODO: Find a way to always calculate a correct frame rate... 636 double frameRate; 637 switch (fStream->codec->codec_type) { 638 case CODEC_TYPE_AUDIO: 639 frameRate = (double)fStream->codec->sample_rate; 640 break; 641 case CODEC_TYPE_VIDEO: 642 frameRate = av_q2d(fStream->r_frame_rate); 643 break; 644 default: 645 frameRate = 1.0; 646 break; 647 } 648 if (frameRate <= 0.0) 649 frameRate = 1.0; 650 return frameRate; 651 } 652 653 654 status_t 655 AVFormatReader::StreamCookie::GetStreamInfo(int64* frameCount, 656 bigtime_t* duration, media_format* format, const void** infoBuffer, 657 size_t* infoSize) const 658 { 659 TRACE("AVFormatReader::StreamCookie::GetStreamInfo(%ld)\n", 660 VirtualIndex()); 661 662 double frameRate = FrameRate(); 663 TRACE(" frameRate: %.4f\n", frameRate); 664 665 // TODO: This is obviously not working correctly for all stream types... 666 // It seems that the calculations here are correct, because they work 667 // for a couple of streams and are in line with the documentation, but 668 // unfortunately, libavformat itself seems to set the time_base and 669 // duration wrongly sometimes. :-( 670 static const int64 kNoPTSValue = 0x8000000000000000LL; 671 // NOTE: For some reasons, I have trouble with the avcodec.h define: 672 // #define AV_NOPTS_VALUE INT64_C(0x8000000000000000) 673 // INT64_C is not defined here. 674 if ((int64)fStream->duration != kNoPTSValue) { 675 *duration = (bigtime_t)(1000000LL * fStream->duration 676 * fStream->time_base.num / fStream->time_base.den); 677 TRACE(" stream duration: %lld, time_base %.4f (%d/%d)\n", 678 fStream->duration, av_q2d(fStream->time_base), 679 fStream->time_base.num, fStream->time_base.den); 680 } else if ((int64)fContext->duration != kNoPTSValue) { 681 *duration = (bigtime_t)(1000000LL * fContext->duration / AV_TIME_BASE); 682 TRACE(" stream duration: %lld (from AVFormatContext)\n", 683 *duration); 684 } else { 685 *duration = 0; 686 TRACE(" stream duration: N/A\n"); 687 } 688 689 TRACE(" duration: %lld or %.2fs\n", *duration, *duration / 1000000.0); 690 691 *frameCount = fStream->nb_frames; 692 if (*frameCount == 0) { 693 // Calculate from duration and frame rate 694 *frameCount = (int64)(*duration * frameRate / 1000000LL); 695 TRACE(" frameCount (calculated): %lld\n", *frameCount); 696 } else 697 TRACE(" frameCount: %lld\n", *frameCount); 698 699 *format = fFormat; 700 701 // TODO: Possibly use fStream->metadata for this? 702 *infoBuffer = 0; 703 *infoSize = 0; 704 705 return B_OK; 706 } 707 708 709 status_t 710 AVFormatReader::StreamCookie::Seek(uint32 flags, int64* frame, 711 bigtime_t* time) 712 { 713 if (fContext == NULL || fStream == NULL) 714 return B_NO_INIT; 715 716 if ((flags & B_MEDIA_SEEK_CLOSEST_FORWARD) != 0) { 717 TRACE_SEEK("AVFormatReader::StreamCookie::Seek() - " 718 "B_MEDIA_SEEK_CLOSEST_FORWARD not supported.\n"); 719 return B_NOT_SUPPORTED; 720 } 721 722 TRACE_SEEK("AVFormatReader::StreamCookie::Seek(%ld, %s %s %s %s, %lld, " 723 "%lld)\n", VirtualIndex(), 724 (flags & B_MEDIA_SEEK_TO_FRAME) ? "B_MEDIA_SEEK_TO_FRAME" : "", 725 (flags & B_MEDIA_SEEK_TO_TIME) ? "B_MEDIA_SEEK_TO_TIME" : "", 726 (flags & B_MEDIA_SEEK_CLOSEST_BACKWARD) ? "B_MEDIA_SEEK_CLOSEST_BACKWARD" : "", 727 (flags & B_MEDIA_SEEK_CLOSEST_FORWARD) ? "B_MEDIA_SEEK_CLOSEST_FORWARD" : "", 728 *frame, *time); 729 730 if ((flags & B_MEDIA_SEEK_TO_FRAME) != 0) 731 *time = (bigtime_t)(*frame * 1000000LL / FrameRate()); 732 733 double timeBase = av_q2d(fStream->time_base); 734 int64_t timeStamp; 735 if ((flags & B_MEDIA_SEEK_TO_FRAME) != 0) { 736 // Can use frame, because stream timeStamp is actually in frame 737 // units. 738 timeStamp = *frame; 739 } else 740 timeStamp = (int64_t)(*time / timeBase / 1000000.0); 741 742 TRACE_SEEK(" time: %.2fs -> %lld, current DTS: %lld (time_base: %f)\n", 743 *time / 1000000.0, timeStamp, fStream->cur_dts, timeBase); 744 745 if (av_seek_frame(fContext, Index(), timeStamp, 0) < 0) { 746 TRACE_SEEK(" av_seek_frame() failed.\n"); 747 return B_ERROR; 748 } 749 750 // Our last packet is toast in any case. 751 av_free_packet(&fPacket); 752 fReusePacket = false; 753 754 return B_OK; 755 } 756 757 758 status_t 759 AVFormatReader::StreamCookie::FindKeyFrame(uint32 flags, int64* frame, 760 bigtime_t* time) const 761 { 762 if (fContext == NULL || fStream == NULL) 763 return B_NO_INIT; 764 765 TRACE_SEEK("AVFormatReader::StreamCookie::FindKeyFrame(%ld, %s %s %s %s, " 766 "%lld, %lld)\n", VirtualIndex(), 767 (flags & B_MEDIA_SEEK_TO_FRAME) ? "B_MEDIA_SEEK_TO_FRAME" : "", 768 (flags & B_MEDIA_SEEK_TO_TIME) ? "B_MEDIA_SEEK_TO_TIME" : "", 769 (flags & B_MEDIA_SEEK_CLOSEST_BACKWARD) ? "B_MEDIA_SEEK_CLOSEST_BACKWARD" : "", 770 (flags & B_MEDIA_SEEK_CLOSEST_FORWARD) ? "B_MEDIA_SEEK_CLOSEST_FORWARD" : "", 771 *frame, *time); 772 773 double frameRate = FrameRate(); 774 if ((flags & B_MEDIA_SEEK_TO_FRAME) != 0) 775 *time = (bigtime_t)(*frame * 1000000LL / frameRate); 776 777 double timeBase = av_q2d(fStream->time_base); 778 int64_t timeStamp; 779 if ((flags & B_MEDIA_SEEK_TO_FRAME) != 0) { 780 // Can use frame, because stream timeStamp is actually in frame 781 // units. 782 timeStamp = *frame; 783 } else 784 timeStamp = (int64_t)(*time / timeBase / 1000000.0); 785 786 TRACE_SEEK(" time: %.2fs -> %lld (time_base: %f)\n", *time / 1000000.0, 787 timeStamp, timeBase); 788 789 int searchFlags = AVSEEK_FLAG_BACKWARD; 790 if ((flags & B_MEDIA_SEEK_CLOSEST_FORWARD) != 0) 791 searchFlags = 0; 792 793 int index = av_index_search_timestamp(fStream, timeStamp, searchFlags); 794 if (index < 0) { 795 TRACE_SEEK(" av_index_search_timestamp() failed.\n"); 796 // Just seek to the beginning of the stream and assume it is a 797 // keyframe... 798 *frame = 0; 799 *time = 0; 800 return B_OK; 801 } 802 803 const AVIndexEntry& entry = fStream->index_entries[index]; 804 timeStamp = entry.timestamp; 805 *time = (bigtime_t)(timeStamp * 1000000.0 * timeBase); 806 807 TRACE_SEEK(" seeked time: %.2fs (%lld)\n", *time / 1000000.0, timeStamp); 808 if ((flags & B_MEDIA_SEEK_TO_FRAME) != 0) { 809 *frame = timeStamp;//*time * frameRate / 1000000LL; 810 TRACE_SEEK(" seeked frame: %lld\n", *frame); 811 } 812 813 return B_OK; 814 } 815 816 817 status_t 818 AVFormatReader::StreamCookie::GetNextChunk(const void** chunkBuffer, 819 size_t* chunkSize, media_header* mediaHeader) 820 { 821 TRACE_PACKET("AVFormatReader::StreamCookie::GetNextChunk()\n"); 822 823 status_t ret = _NextPacket(false); 824 if (ret != B_OK) { 825 *chunkBuffer = NULL; 826 *chunkSize = 0; 827 return ret; 828 } 829 830 // NOTE: AVPacket has a field called "convergence_duration", for which 831 // the documentation is quite interesting. It sounds like it could be 832 // used to know the time until the next I-Frame in streams that don't 833 // let you know the position of keyframes in another way (like through 834 // the index). 835 836 // According to libavformat documentation, fPacket is valid until the 837 // next call to av_read_frame(). This is what we want and we can share 838 // the memory with the least overhead. 839 *chunkBuffer = fPacket.data; 840 *chunkSize = fPacket.size; 841 842 if (mediaHeader != NULL) { 843 mediaHeader->type = fFormat.type; 844 mediaHeader->buffer = 0; 845 mediaHeader->destination = -1; 846 mediaHeader->time_source = -1; 847 mediaHeader->size_used = fPacket.size; 848 //TRACE(" PTS: %lld (time_base.num: %d, .den: %d)\n", 849 //fPacket.pts, fStream->time_base.num, fStream->time_base.den); 850 mediaHeader->start_time = (bigtime_t)(1000000.0 * fPacket.pts 851 / av_q2d(fStream->time_base)); 852 mediaHeader->file_pos = fPacket.pos; 853 mediaHeader->data_offset = 0; 854 switch (mediaHeader->type) { 855 case B_MEDIA_RAW_AUDIO: 856 break; 857 case B_MEDIA_ENCODED_AUDIO: 858 mediaHeader->u.encoded_audio.buffer_flags 859 = (fPacket.flags & PKT_FLAG_KEY) ? B_MEDIA_KEY_FRAME : 0; 860 break; 861 case B_MEDIA_RAW_VIDEO: 862 mediaHeader->u.raw_video.line_count 863 = fFormat.u.raw_video.display.line_count; 864 break; 865 case B_MEDIA_ENCODED_VIDEO: 866 mediaHeader->u.encoded_video.field_flags 867 = (fPacket.flags & PKT_FLAG_KEY) ? B_MEDIA_KEY_FRAME : 0; 868 mediaHeader->u.encoded_video.line_count 869 = fFormat.u.encoded_video.output.display.line_count; 870 break; 871 default: 872 break; 873 } 874 } 875 876 return B_OK; 877 } 878 879 880 // #pragma mark - 881 882 883 /*static*/ int 884 AVFormatReader::StreamCookie::_Read(void* cookie, uint8* buffer, 885 int bufferSize) 886 { 887 TRACE_IO("AVFormatReader::StreamCookie::_Read(%p, %p, %d)\n", 888 cookie, buffer, bufferSize); 889 890 StreamCookie* stream = reinterpret_cast<StreamCookie*>(cookie); 891 892 BAutolock _(stream->fStreamLock); 893 894 if (stream->fPosition != stream->fSource->Position()) { 895 off_t position 896 = stream->fSource->Seek(stream->fPosition, SEEK_SET); 897 if (position != stream->fPosition) 898 return -1; 899 } 900 901 ssize_t read = stream->fSource->Read(buffer, bufferSize); 902 if (read > 0) 903 stream->fPosition += read; 904 905 TRACE_IO(" read: %ld\n", read); 906 return (int)read; 907 908 } 909 910 911 /*static*/ off_t 912 AVFormatReader::StreamCookie::_Seek(void* cookie, off_t offset, int whence) 913 { 914 TRACE_IO("AVFormatReader::StreamCookie::_Seek(%p, %lld, %d)\n", 915 cookie, offset, whence); 916 917 StreamCookie* stream = reinterpret_cast<StreamCookie*>(cookie); 918 919 BAutolock _(stream->fStreamLock); 920 921 // Support for special file size retrieval API without seeking 922 // anywhere: 923 if (whence == AVSEEK_SIZE) { 924 off_t size; 925 if (stream->fSource->GetSize(&size) == B_OK) 926 return size; 927 return -1; 928 } 929 930 // If not requested to seek to an absolute position, we need to 931 // confirm that the stream is currently at the position that we 932 // think it is. 933 if (whence != SEEK_SET 934 && stream->fPosition != stream->fSource->Position()) { 935 off_t position 936 = stream->fSource->Seek(stream->fPosition, SEEK_SET); 937 if (position != stream->fPosition) 938 return -1; 939 } 940 941 off_t position = stream->fSource->Seek(offset, whence); 942 TRACE_IO(" position: %lld\n", position); 943 if (position < 0) 944 return -1; 945 946 stream->fPosition = position; 947 948 return position; 949 } 950 951 952 status_t 953 AVFormatReader::StreamCookie::_NextPacket(bool reuse) 954 { 955 TRACE_PACKET("AVFormatReader::StreamCookie::_NextPacket(%d)\n", reuse); 956 957 if (fReusePacket) { 958 // The last packet was marked for reuse, so we keep using it. 959 TRACE_PACKET(" re-using last packet\n"); 960 fReusePacket = reuse; 961 return B_OK; 962 } 963 964 av_free_packet(&fPacket); 965 966 while (true) { 967 if (av_read_frame(fContext, &fPacket) < 0) { 968 fReusePacket = false; 969 return B_LAST_BUFFER_ERROR; 970 } 971 972 if (fPacket.stream_index == Index()) 973 break; 974 975 // This is a packet from another stream, ignore it. 976 av_free_packet(&fPacket); 977 } 978 979 // Mark this packet with the new reuse flag. 980 fReusePacket = reuse; 981 return B_OK; 982 } 983 984 985 // #pragma mark - AVFormatReader 986 987 988 AVFormatReader::AVFormatReader() 989 : 990 fStreams(NULL), 991 fStreamLock("stream lock") 992 { 993 TRACE("AVFormatReader::AVFormatReader\n"); 994 } 995 996 997 AVFormatReader::~AVFormatReader() 998 { 999 TRACE("AVFormatReader::~AVFormatReader\n"); 1000 if (fStreams != NULL) { 1001 delete fStreams[0]; 1002 delete[] fStreams; 1003 } 1004 } 1005 1006 1007 // #pragma mark - 1008 1009 1010 const char* 1011 AVFormatReader::Copyright() 1012 { 1013 // TODO: Could not find the equivalent in libavformat >= version 53. 1014 // if (fStreams != NULL && fStreams[0] != NULL) 1015 // return fStreams[0]->Context()->copyright; 1016 // TODO: Return copyright of the file instead! 1017 return "Copyright 2009, Stephan Aßmus"; 1018 } 1019 1020 1021 status_t 1022 AVFormatReader::Sniff(int32* _streamCount) 1023 { 1024 TRACE("AVFormatReader::Sniff\n"); 1025 1026 BPositionIO* source = dynamic_cast<BPositionIO*>(Source()); 1027 if (source == NULL) { 1028 TRACE(" not a BPositionIO, but we need it to be one.\n"); 1029 return B_NOT_SUPPORTED; 1030 } 1031 1032 StreamCookie* stream = new(std::nothrow) StreamCookie(source, 1033 &fStreamLock); 1034 if (stream == NULL) { 1035 ERROR("AVFormatReader::Sniff() - failed to allocate StreamCookie\n"); 1036 return B_NO_MEMORY; 1037 } 1038 1039 ObjectDeleter<StreamCookie> streamDeleter(stream); 1040 1041 status_t ret = stream->Open(); 1042 if (ret != B_OK) { 1043 TRACE(" failed to detect stream: %s\n", strerror(ret)); 1044 return ret; 1045 } 1046 1047 delete[] fStreams; 1048 fStreams = NULL; 1049 1050 int32 streamCount = stream->CountStreams(); 1051 if (streamCount == 0) { 1052 TRACE(" failed to detect any streams: %s\n", strerror(ret)); 1053 return B_ERROR; 1054 } 1055 1056 fStreams = new(std::nothrow) StreamCookie*[streamCount]; 1057 if (fStreams == NULL) { 1058 ERROR("AVFormatReader::Sniff() - failed to allocate streams\n"); 1059 return B_NO_MEMORY; 1060 } 1061 1062 memset(fStreams, 0, sizeof(StreamCookie*) * streamCount); 1063 fStreams[0] = stream; 1064 streamDeleter.Detach(); 1065 1066 #ifdef TRACE_AVFORMAT_READER 1067 dump_format(const_cast<AVFormatContext*>(stream->Context()), 0, "", 0); 1068 #endif 1069 1070 if (_streamCount != NULL) 1071 *_streamCount = streamCount; 1072 1073 return B_OK; 1074 } 1075 1076 1077 void 1078 AVFormatReader::GetFileFormatInfo(media_file_format* mff) 1079 { 1080 TRACE("AVFormatReader::GetFileFormatInfo\n"); 1081 1082 if (fStreams == NULL) 1083 return; 1084 1085 // The first cookie is always there! 1086 const AVFormatContext* context = fStreams[0]->Context(); 1087 1088 if (context == NULL || context->iformat == NULL) { 1089 TRACE(" no AVFormatContext or AVInputFormat!\n"); 1090 return; 1091 } 1092 1093 const DemuxerFormat* format = demuxer_format_for(context->iformat); 1094 1095 mff->capabilities = media_file_format::B_READABLE 1096 | media_file_format::B_KNOWS_ENCODED_VIDEO 1097 | media_file_format::B_KNOWS_ENCODED_AUDIO 1098 | media_file_format::B_IMPERFECTLY_SEEKABLE; 1099 1100 if (format != NULL) { 1101 // TODO: Check if AVInputFormat has audio only and then use 1102 // format->audio_family! 1103 mff->family = format->video_family; 1104 } else { 1105 TRACE(" no DemuxerFormat for AVInputFormat!\n"); 1106 mff->family = B_MISC_FORMAT_FAMILY; 1107 } 1108 1109 mff->version = 100; 1110 1111 if (format != NULL) { 1112 strcpy(mff->mime_type, format->mime_type); 1113 } else { 1114 // TODO: Would be nice to be able to provide this from AVInputFormat, 1115 // maybe by extending the FFmpeg code itself (all demuxers). 1116 strcpy(mff->mime_type, ""); 1117 } 1118 1119 if (context->iformat->extensions != NULL) 1120 strcpy(mff->file_extension, context->iformat->extensions); 1121 else { 1122 TRACE(" no file extensions for AVInputFormat.\n"); 1123 strcpy(mff->file_extension, ""); 1124 } 1125 1126 if (context->iformat->name != NULL) 1127 strcpy(mff->short_name, context->iformat->name); 1128 else { 1129 TRACE(" no short name for AVInputFormat.\n"); 1130 strcpy(mff->short_name, ""); 1131 } 1132 1133 if (context->iformat->long_name != NULL) 1134 strcpy(mff->pretty_name, context->iformat->long_name); 1135 else { 1136 if (format != NULL) 1137 strcpy(mff->pretty_name, format->pretty_name); 1138 else 1139 strcpy(mff->pretty_name, ""); 1140 } 1141 } 1142 1143 1144 // #pragma mark - 1145 1146 1147 status_t 1148 AVFormatReader::AllocateCookie(int32 streamIndex, void** _cookie) 1149 { 1150 TRACE("AVFormatReader::AllocateCookie(%ld)\n", streamIndex); 1151 1152 BAutolock _(fStreamLock); 1153 1154 if (fStreams == NULL) 1155 return B_NO_INIT; 1156 1157 if (streamIndex < 0 || streamIndex >= fStreams[0]->CountStreams()) 1158 return B_BAD_INDEX; 1159 1160 if (_cookie == NULL) 1161 return B_BAD_VALUE; 1162 1163 StreamCookie* cookie = fStreams[streamIndex]; 1164 if (cookie == NULL) { 1165 // Allocate the cookie 1166 BPositionIO* source = dynamic_cast<BPositionIO*>(Source()); 1167 if (source == NULL) { 1168 TRACE(" not a BPositionIO, but we need it to be one.\n"); 1169 return B_NOT_SUPPORTED; 1170 } 1171 1172 cookie = new(std::nothrow) StreamCookie(source, &fStreamLock); 1173 if (cookie == NULL) { 1174 ERROR("AVFormatReader::Sniff() - failed to allocate " 1175 "StreamCookie\n"); 1176 return B_NO_MEMORY; 1177 } 1178 1179 status_t ret = cookie->Open(); 1180 if (ret != B_OK) { 1181 TRACE(" stream failed to open: %s\n", strerror(ret)); 1182 delete cookie; 1183 return ret; 1184 } 1185 } 1186 1187 status_t ret = cookie->Init(streamIndex); 1188 if (ret != B_OK) { 1189 TRACE(" stream failed to initialize: %s\n", strerror(ret)); 1190 // NOTE: Never delete the first stream! 1191 if (streamIndex != 0) 1192 delete cookie; 1193 return ret; 1194 } 1195 1196 fStreams[streamIndex] = cookie; 1197 *_cookie = cookie; 1198 1199 return B_OK; 1200 } 1201 1202 1203 status_t 1204 AVFormatReader::FreeCookie(void *_cookie) 1205 { 1206 BAutolock _(fStreamLock); 1207 1208 StreamCookie* cookie = reinterpret_cast<StreamCookie*>(_cookie); 1209 1210 // NOTE: Never delete the first cookie! 1211 if (cookie != NULL && cookie->VirtualIndex() != 0) { 1212 if (fStreams != NULL) 1213 fStreams[cookie->VirtualIndex()] = NULL; 1214 delete cookie; 1215 } 1216 1217 return B_OK; 1218 } 1219 1220 1221 // #pragma mark - 1222 1223 1224 status_t 1225 AVFormatReader::GetStreamInfo(void* _cookie, int64* frameCount, 1226 bigtime_t* duration, media_format* format, const void** infoBuffer, 1227 size_t* infoSize) 1228 { 1229 TRACE("AVFormatReader::GetStreamInfo()\n"); 1230 1231 // BAutolock _(fStreamLock); 1232 1233 StreamCookie* cookie = reinterpret_cast<StreamCookie*>(_cookie); 1234 return cookie->GetStreamInfo(frameCount, duration, format, infoBuffer, 1235 infoSize); 1236 } 1237 1238 1239 status_t 1240 AVFormatReader::Seek(void* _cookie, uint32 seekTo, int64* frame, 1241 bigtime_t* time) 1242 { 1243 TRACE_SEEK("AVFormatReader::Seek()\n"); 1244 1245 // BAutolock _(fStreamLock); 1246 1247 StreamCookie* cookie = reinterpret_cast<StreamCookie*>(_cookie); 1248 return cookie->Seek(seekTo, frame, time); 1249 } 1250 1251 1252 status_t 1253 AVFormatReader::FindKeyFrame(void* _cookie, uint32 flags, int64* frame, 1254 bigtime_t* time) 1255 { 1256 TRACE_SEEK("AVFormatReader::FindKeyFrame()\n"); 1257 1258 // BAutolock _(fStreamLock); 1259 1260 StreamCookie* cookie = reinterpret_cast<StreamCookie*>(_cookie); 1261 return cookie->FindKeyFrame(flags, frame, time); 1262 } 1263 1264 1265 status_t 1266 AVFormatReader::GetNextChunk(void* _cookie, const void** chunkBuffer, 1267 size_t* chunkSize, media_header* mediaHeader) 1268 { 1269 TRACE_PACKET("AVFormatReader::GetNextChunk()\n"); 1270 1271 // BAutolock _(fStreamLock); 1272 1273 StreamCookie* cookie = reinterpret_cast<StreamCookie*>(_cookie); 1274 return cookie->GetNextChunk(chunkBuffer, chunkSize, mediaHeader); 1275 } 1276 1277 1278