24 #include <com/avpkit/ferry/Logger.h>
25 #include <com/avpkit/ferry/RefPointer.h>
27 #include <com/avpkit/core/Global.h>
28 #include <com/avpkit/core/StreamCoder.h>
29 #include <com/avpkit/core/Codec.h>
30 #include <com/avpkit/core/Rational.h>
31 #include <com/avpkit/core/AudioSamples.h>
32 #include <com/avpkit/core/VideoPicture.h>
33 #include <com/avpkit/core/Packet.h>
34 #include <com/avpkit/core/Property.h>
35 #include <com/avpkit/core/MetaData.h>
36 #include <com/avpkit/ferry/JNIHelper.h>
39 #include <libavutil/dict.h>
40 #include <libavutil/channel_layout.h>
41 #include <libavutil/samplefmt.h>
42 #include <libavcodec/mediacodec.h>
47 VS_LOG_SETUP(VS_CPP_PACKAGE);
54 StreamCoder::StreamCoder() :
60 mDirection = DECODING;
63 mAudioFrameBuffer = 0;
64 mBytesInFrameBuffer = 0;
65 mPtsOfFrameBuffer = Global::NO_PTS;
66 mFakePtsTimeBase = IRational::make(1, AV_TIME_BASE);
67 mFakeNextPts = Global::NO_PTS;
68 mFakeCurrPts = Global::NO_PTS;
69 mLastPtsEncoded = Global::NO_PTS;
71 mLastExternallySetTimeStamp = Global::NO_PTS;
72 mDefaultAudioFrameSize = 576;
73 mNumDroppedFrames = 0;
74 mAutomaticallyStampPacketsForStream =
true;
75 for(uint32_t i = 0; i <
sizeof(mPtsBuffer)/
sizeof(mPtsBuffer[0]); i++)
77 mPtsBuffer[i] = Global::NO_PTS;
81 StreamCoder::~StreamCoder()
87 StreamCoder::resetOptions(AVCodecContext* ctx)
91 if (ctx->codec && ctx->codec->priv_class && ctx->priv_data)
92 av_opt_free(ctx->priv_data);
94 av_freep(&ctx->priv_data);
104 VS_LOG_DEBUG(
"Closing dangling StreamCoder");
105 (void) this->close();
108 mAutomaticallyStampPacketsForStream =
true;
115 resetOptions(mCodecContext);
118 av_freep(&mCodecContext->extradata);
119 av_freep(&mCodecContext->subtitle_header);
120 avcodec_free_context(&mCodecContext);
123 mediacodec_free_context(mCodecContext);
125 av_freep(&mCodecContext);
135 StreamCoder :: readyAVContexts(
136 Direction aDirection,
140 AVCodecContext *avContext,
141 const AVCodec *avCodec)
149 aCoder->mCodec = Codec::make(avCodec);
150 }
else if (aDirection == ENCODING) {
151 aCoder->mCodec =
static_cast<Codec*
>(ICodec::findEncodingCodecByIntID(avContext->codec_id));
153 aCoder->mCodec =
static_cast<Codec*
>(ICodec::findDecodingCodecByIntID(avContext->codec_id));
156 aCoder->mCodec.reset(aCodec,
true);
158 aCodec = aCoder->mCodec.value();
159 avCodec = aCodec ? aCodec->getAVCodec() : 0;
160 if (aCoder->mCodecContext) {
163 resetOptions(aCoder->mCodecContext);
165 aCoder->mCodecContext = avContext;
166 aCoder->setStream(aStream,
true);
167 aCoder->mDirection = aDirection;
169 avContext->opaque = aCodec;
174 avContext->codec_id = avCodec ? avCodec->id : AV_CODEC_ID_NONE;
175 avContext->codec_type = avCodec ? avCodec->type : AVMEDIA_TYPE_UNKNOWN;
176 avContext->codec = avCodec;
178 if (aDirection == DECODING && aStream)
179 avContext->pkt_timebase = aStream->getAVStream()->time_base;
181 switch (avContext->codec_type)
183 case AVMEDIA_TYPE_AUDIO:
184 if (avContext->block_align == 1 && avContext->codec_id == AV_CODEC_ID_MP3)
185 avContext->block_align = 0;
186 if (avContext->codec_id == AV_CODEC_ID_AC3)
187 avContext->block_align = 0;
193 VS_LOG_TRACE(
"StreamCoder %p codec set to: %s [%s]",
195 avCodec ? avCodec->name :
"unknown",
196 avCodec ? avCodec->long_name :
"unknown; caller must call IStreamCoder.setCodec(ICodec)");
197 if (!avCodec && (avContext->codec_type == AVMEDIA_TYPE_AUDIO || avContext->codec_type == AVMEDIA_TYPE_VIDEO)) {
198 VS_LOG_WARN(
"DEPRECATED; StreamCoder %p created without Codec. Caller must call"
199 " IStreamCoder.setCodec(ICodec) before any other methods", aCoder);
210 const AVCodec* avCodec = NULL;
213 VS_LOG_INFO(
"Cannot set codec to null codec");
216 avCodec = codec->getAVCodec();
218 if (!mCodecContext) {
219 VS_LOG_ERROR(
"No codec context");
223 if (mCodecContext->codec_id != AV_CODEC_ID_NONE || mCodecContext->codec) {
224 VS_LOG_INFO(
"Codec already set to codec: %d. Ignoring setCodec call",
225 mCodecContext->codec_id);
229 if (mCodec.value() == aCodec) {
237 resetOptions(mCodecContext);
238 av_freep(&mCodecContext->extradata);
239 av_freep(&mCodecContext->subtitle_header);
240 avcodec_free_context(&mCodecContext);
243 mCodecContext = avcodec_alloc_context3(avCodec);
246 readyAVContexts(mDirection,
257 setCodec((int32_t)
id);
261 StreamCoder::setCodec(int32_t
id)
264 if (ENCODING == mDirection)
266 codec = Codec::findEncodingCodecByIntID(
id);
270 codec = Codec::findDecodingCodecByIntID(
id);
273 setCodec(codec.
value());
277 StreamCoder::make(Direction direction, ICodec::ID
id)
280 StreamCoder* retval = NULL;
281 if (ENCODING == direction)
283 codec = Codec::findEncodingCodec(
id);
287 codec = Codec::findDecodingCodec(
id);
290 retval = StreamCoder::make(direction, codec.
value());
295 StreamCoder :: make (Direction direction, Codec* codec)
297 StreamCoder* retval= NULL;
301 AVCodecContext* codecCtx= NULL;
302 const AVCodec* avCodec = NULL;
305 avCodec = codec->getAVCodec();
307 retval = StreamCoder::make();
309 throw std::bad_alloc();
311 codecCtx = avcodec_alloc_context3(avCodec);
320 throw std::runtime_error(
"could not initialize codec");
322 catch (std::exception & e)
324 VS_REF_RELEASE(retval);
330 StreamCoder::make(Direction direction, IStreamCoder* aCoder)
332 StreamCoder *retval = NULL;
333 StreamCoder *coder =
static_cast<StreamCoder*
> (aCoder);
338 throw std::runtime_error(
"cannot make stream coder from null coder");
342 codecToUse = coder->getCodec();
344 retval = make(direction, codecToUse.
value());
346 throw std::bad_alloc();
348 AVCodecContext* codec = retval->mCodecContext;
349 AVCodecContext* icodec = coder->mCodecContext;
354 av_freep(&codec->extradata);
355 av_freep(&codec->subtitle_header);
359 avcodec_copy_context(codec, icodec);
362 codec->codec = icodec->codec;
366 double base = streamBase ? streamBase->getDouble() : 0;
368 if (base && av_q2d(icodec->time_base) * icodec->ticks_per_frame > base
369 && base < 1.0 / 1000)
371 codec->time_base.num *= icodec->ticks_per_frame;
373 if (!codec->time_base.num || !codec->time_base.den)
378 codec->time_base.num = iStreamBase->getNumerator();
379 codec->time_base.den = iStreamBase->getDenominator();
390 throw std::runtime_error(
"could not initialize AVContext");
393 catch (std::exception &e)
395 VS_LOG_WARN(
"Error: %s", e.what());
396 VS_REF_RELEASE(retval);
403 StreamCoder::make(Direction direction,
404 AVCodecParameters *codecpar,
const AVCodec* avCodec, Stream* stream)
406 StreamCoder* retval = NULL;
407 AVCodecContext* codecCtx = NULL;
409 retval = StreamCoder::make();
411 throw std::bad_alloc();
413 codecCtx = avcodec_alloc_context3(avCodec);
414 if (codecCtx && codecpar){
415 if (avcodec_parameters_to_context(codecCtx, codecpar) < 0)
416 throw std::runtime_error(
"could not initialize codec");
426 throw std::runtime_error(
"could not initialize AVContext");
428 catch (std::exception & e)
430 VS_REF_RELEASE(retval);
437 StreamCoder::make(
Direction direction, AVCodecContext * codecCtx,
438 const AVCodec* avCodec,
Stream* stream)
447 retval = StreamCoder::make();
455 throw std::runtime_error(
"could not initialize codec");
457 catch (std::exception &e)
459 VS_REF_RELEASE(retval);
467 StreamCoder::getStream()
470 VS_REF_ACQUIRE(mStream);
475 StreamCoder::getCodec()
477 return mCodec ? mCodec.get() : 0;
481 StreamCoder::getCodecType()
490 VS_LOG_WARN(
"Attempt to get CodecType from uninitialized StreamCoder");
496 StreamCoder::getCodecID()
501 retval = (
ICodec::ID) mCodecContext->codec_id;
505 VS_LOG_WARN(
"Attempt to get CodecID from uninitialized StreamCoder");
511 StreamCoder::getBitRate()
513 return (mCodecContext ? mCodecContext->bit_rate : -1);
516 StreamCoder::setBitRate(int32_t val)
518 if (mCodecContext && !mOpened)
519 mCodecContext->bit_rate = val;
522 StreamCoder::getBitRateTolerance()
524 return (mCodecContext ? mCodecContext->bit_rate_tolerance : -1);
527 StreamCoder::setBitRateTolerance(int32_t val)
529 if (mCodecContext && !mOpened)
530 mCodecContext->bit_rate_tolerance = val;
533 StreamCoder::getHeight()
535 return (mCodecContext ? mCodecContext->height : -1);
539 StreamCoder::setHeight(int32_t val)
541 if (mCodecContext && !mOpened)
542 mCodecContext->height = val;
546 StreamCoder::getWidth()
548 return (mCodecContext ? mCodecContext->width : -1);
552 StreamCoder::setWidth(int32_t val)
554 if (mCodecContext && !mOpened)
555 mCodecContext->width = val;
559 StreamCoder::getTimeBase()
567 if (mCodecContext && mCodecContext->time_base.den
568 && mCodecContext->time_base.num)
570 retval = Rational::make(&mCodecContext->time_base);
572 else if (mAutomaticallyStampPacketsForStream)
574 retval = mStream ? mStream->getTimeBase() : 0;
583 if (mCodecContext && src && !mOpened)
590 VS_LOG_INFO(
"Failed to setTimeBase on StreamCoder");
595 StreamCoder::getNextPredictedPts()
601 StreamCoder::getFrameRate()
603 if (mCodecContext && mCodecContext->framerate.num > 0) {
604 return Rational::make(&mCodecContext->framerate);
606 return (mStream ? mStream->getFrameRate() : 0);
612 if (mStream && !mOpened)
613 mStream->setFrameRate(src);
614 if (mCodecContext && !mOpened && src){
622 StreamCoder::getNumPicturesInGroupOfPictures()
624 return (mCodecContext ? mCodecContext->gop_size : -1);
628 StreamCoder::setNumPicturesInGroupOfPictures(int32_t val)
630 if (mCodecContext && !mOpened)
631 mCodecContext->gop_size = val;
635 StreamCoder::getPixelType()
644 type = (int32_t) retval;
645 if (type != mCodecContext->pix_fmt) {
646 VS_LOG_ERROR(
"Undefined pixel format type: %d", mCodecContext->pix_fmt);
647 retval = IPixelFormat::NONE;
656 if (mCodecContext && !mOpened)
658 mCodecContext->pix_fmt = (AVPixelFormat) type;
663 StreamCoder::getSampleRate()
665 return (mCodecContext ? mCodecContext->sample_rate : -1);
669 StreamCoder::setSampleRate(int32_t val)
671 if (mCodecContext && !mOpened && val > 0)
672 mCodecContext->sample_rate = val;
676 StreamCoder::getSampleFormat()
685 if (mCodecContext && !mOpened && val > 0)
686 mCodecContext->sample_fmt = (
enum AVSampleFormat) val;
690 StreamCoder::getChannels()
692 return (mCodecContext ? mCodecContext->channels : -1);
696 StreamCoder::setChannels(int32_t val)
698 if (mCodecContext && !mOpened && val > 0)
699 mCodecContext->channels = val;
703 StreamCoder::getGlobalQuality()
705 return (mCodecContext ? mCodecContext->global_quality : FF_LAMBDA_MAX);
709 StreamCoder::setGlobalQuality(int32_t newQuality)
711 if (newQuality < 0 || newQuality > FF_LAMBDA_MAX)
712 newQuality = FF_LAMBDA_MAX;
714 mCodecContext->global_quality = newQuality;
718 StreamCoder::getFlags()
720 return (mCodecContext ? mCodecContext->flags : 0);
724 StreamCoder::setFlags(int32_t newFlags)
727 mCodecContext->flags = newFlags;
735 result = mCodecContext->flags & flag;
746 mCodecContext->flags |= flag;
750 mCodecContext->flags &= (~flag);
759 return open(NULL, NULL);
765 AVDictionary* tmp= NULL;
769 swrContext = swr_alloc();
771 throw std::runtime_error(
"no codec context");
781 throw std::runtime_error(
"no codec set for coder");
787 throw new std::runtime_error(
"wow... who's passing us crap?");
794 if (mDirection == ENCODING && mCodecContext->time_base.num == 0)
796 if (this->getCodecType() == ICodec::CODEC_TYPE_AUDIO)
798 if (mCodecContext->sample_rate > 0)
800 mCodecContext->time_base.num = 1;
801 mCodecContext->time_base.den = mCodecContext->sample_rate;
805 throw std::runtime_error(
"no sample rate set on coder");
810 if (mDirection == ENCODING && this->getCodecType() == ICodec::CODEC_TYPE_AUDIO && !mCodecContext->channel_layout)
812 mCodecContext->channel_layout = av_get_default_channel_layout(mCodecContext->channels);
822 if (format && mDirection == ENCODING && format->getOutputFlag(
823 IContainerFormat::FLAG_GLOBALHEADER))
825 this->setFlag(FLAG_GLOBAL_HEADER,
true);
841 retval = avcodec_open2(mCodecContext, mCodec->getAVCodec(), &tmp);
850 throw std::runtime_error(
"could not open codec");
854 if (mDirection == ENCODING && mStream) {
855 avcodec_parameters_from_context(mStream->getAVStream()->codecpar, mCodecContext);
860 mNumDroppedFrames = 0;
861 mSamplesCoded = mSamplesForEncoding = mLastExternallySetTimeStamp = 0;
862 mFakeCurrPts = mFakeNextPts = mLastPtsEncoded = Global::NO_PTS;
863 for(uint32_t i = 0; i <
sizeof(mPtsBuffer)/
sizeof(mPtsBuffer[0]); i++)
865 mPtsBuffer[i] = Global::NO_PTS;
869 if (this->getCodecType() == ICodec::CODEC_TYPE_AUDIO)
871 int32_t frame_bytes = getAudioFrameSize() * getChannels()
872 * IAudioSamples::findSampleBitDepth(
874 if (frame_bytes <= 0)
875 frame_bytes = 192000;
877 if (!mAudioFrameBuffer || mAudioFrameBuffer->getBufferSize()
880 mAudioFrameBuffer = IBuffer::make(
this, frame_bytes);
881 mBytesInFrameBuffer = 0;
887 throw std::runtime_error(
"really... seriously?");
888 unsetOptions->
copy(tmp);
891 catch (std::bad_alloc & e)
895 catch (std::exception & e)
897 VS_LOG_WARN(
"Error: %s", e.what());
909 if (mCodecContext && mOpened)
911 retval = avcodec_close(mCodecContext);
912 swr_free(&swrContext);
915 mBytesInFrameBuffer = 0;
921 int32_t startingByte)
929 samples->
setComplete(
false, 0, getSampleRate(), getChannels(),
930 IAudioSamples::FMT_S16, Global::NO_PTS);
932 VS_LOG_WARN(
"Attempting to decode when not ready; no samples");
940 VS_LOG_WARN(
"Attempting to decode when not ready; codec not opened");
943 if (!mCodecContext) {
944 VS_LOG_WARN(
"Attempting to decode when not ready; internal context not allocated");
947 if (mDirection != DECODING) {
948 VS_LOG_WARN(
"Attempting to decode when not ready; StreamCoder is set to encode, not decode");
951 if (!mCodec || !mCodec->canDecode()) {
952 VS_LOG_WARN(
"Attempting to decode when not ready; codec set cannot decode");
955 if (getCodecType() != ICodec::CODEC_TYPE_AUDIO) {
956 VS_LOG_WARN(
"Attempting to decode when not ready; codec set is not an audio codec");
962 int32_t inBufSize = 0;
969 inBufSize = packet->
getSize() - startingByte;
971 if (inBufSize > 0 && outBufSize > 0 || mCodec->getAVCodec()->capabilities & AV_CODEC_CAP_DELAY)
975 uint8_t * outBuf = 0;
976 uint64_t outChannelLayout;
977 AVFrame* frame = av_frame_alloc();
982 VS_ASSERT(buffer,
"no buffer in packet!");
984 inBuf = (uint8_t*) buffer->getBytes(startingByte, inBufSize);
985 VS_ASSERT(inBuf,
"no in buffer");
988 outBuf = (uint8_t*) samples->getRawSamples(0);
989 VS_ASSERT(outBuf,
"no out buffer");
993 VS_LOG_TRACE(
"Attempting decodeAudio(%p, %p, %d, %p, %d);",
1001 av_init_packet(&pkt);
1007 if (packet && packet->getAVPacket())
1008 pkt = *packet->getAVPacket();
1011 pkt.size = inBufSize;
1012 mCodecContext->reordered_opaque = packet->
getPts();
1019 retval = avcodec_decode_audio4(mCodecContext, frame, &got_frame, &pkt);
1026 outChannelLayout = frame->channel_layout;
1032 if (retval >= 0 && got_frame) {
1033 if (!swr_is_initialized(swrContext)){
1034 swr_alloc_set_opts(swrContext,
1036 frame->channel_layout == 0 ? av_get_default_channel_layout(frame->channels) : frame->channel_layout,
1040 frame->channel_layout == 0 ? av_get_default_channel_layout(frame->channels) : frame->channel_layout,
1041 mCodecContext->sample_fmt,
1045 swr_init(swrContext);
1048 int outChannels = av_frame_get_channels(frame);
1049 uint8_t* output[1] = {outBuf};
1051 int out_samples = swr_convert(swrContext, output, frame->nb_samples, (
const uint8_t**)frame->extended_data, frame->nb_samples);
1052 if (out_samples < 0) {
1053 VS_LOG_ERROR(
"fail to convert samples: %s", Error::make(out_samples)->getDescription());
1057 int data_size = av_samples_get_buffer_size(NULL,
1072 if (outBufSize < data_size) {
1073 VS_LOG_ERROR(
"Output buffer is not large enough; no audio actually returned");
1077 outBufSize = data_size;
1083 VS_LOG_TRACE(
"Finished %d decodeAudio(%p, %p, %d, %p, %d);",
1099 int32_t bytesPerSample = (IAudioSamples::findSampleBitDepth(format) / 8
1101 int32_t numSamples = outBufSize / bytesPerSample;
1105 this->mStream ? this->mStream->getTimeBase() : 0;
1107 timeBase = this->getTimeBase();
1109 int64_t packetTs = frame->best_effort_timestamp;
1113 if (packetTs == Global::NO_PTS && mFakeNextPts == Global::NO_PTS)
1117 VS_LOG_TRACE(
"Setting fake pts to 0");
1120 if (packetTs != Global::NO_PTS)
1123 if (timeBase->getNumerator() != 0 && timeBase->getDenominator() != 0)
1125 int64_t tsDelta = Global::NO_PTS;
1126 if (mFakeNextPts != Global::NO_PTS)
1128 int64_t fakeTsInStreamTimeBase = Global::NO_PTS;
1130 fakeTsInStreamTimeBase = timeBase->rescale(mFakeNextPts,
1131 mFakePtsTimeBase.value());
1132 tsDelta = fakeTsInStreamTimeBase - packetTs;
1140 if (mFakeNextPts != Global::NO_PTS && (tsDelta >= -1 && tsDelta
1144 VS_LOG_TRACE(
"Keeping mFakeNextPts: %lld", mFakeNextPts);
1149 int64_t packetTsInMicroseconds = mFakePtsTimeBase->rescale(
1150 packetTs, timeBase.
value());
1151 VS_LOG_TRACE(
"%p Gap in audio (%lld); Resetting calculated ts from %lld to %lld",
1155 packetTsInMicroseconds);
1156 mLastExternallySetTimeStamp = packetTsInMicroseconds;
1158 mFakeNextPts = mLastExternallySetTimeStamp;
1163 mFakeCurrPts = mFakeNextPts;
1167 mSamplesCoded += numSamples;
1168 mFakeNextPts = mLastExternallySetTimeStamp
1169 + IAudioSamples::samplesToDefaultPts(mSamplesCoded,
1174 samples->
setComplete(numSamples > 0, numSamples, getSampleRate(),
1178 av_frame_free(&frame);
1188 int32_t retval = -1;
1193 frame->
setComplete(
false, IPixelFormat::NONE, -1, -1, mFakeCurrPts);
1196 VS_LOG_WARN(
"Attempting to decode when not ready; no frame");
1204 VS_LOG_WARN(
"Attempting to decode when not ready; codec not opened");
1207 if (!mCodecContext) {
1208 VS_LOG_WARN(
"Attempting to decode when not ready; internal context not allocated");
1211 if (mDirection != DECODING) {
1212 VS_LOG_WARN(
"Attempting to decode when not ready; StreamCoder is set to encode, not decode");
1215 if (!mCodec || !mCodec->canDecode()) {
1216 VS_LOG_WARN(
"Attempting to decode when not ready; codec set cannot decode");
1219 if (getCodecType() != ICodec::CODEC_TYPE_VIDEO) {
1220 VS_LOG_WARN(
"Attempting to decode when not ready; codec set is not a video codec");
1224 AVFrame *avFrame = av_frame_alloc();
1227 int frameFinished = 0;
1228 int32_t inBufSize = 0;
1229 uint8_t * inBuf = 0;
1232 inBufSize = packet->
getSize() - byteOffset;
1234 VS_ASSERT(buffer,
"no buffer in packet?");
1236 inBuf = (uint8_t*) buffer->getBytes(byteOffset, inBufSize);
1238 VS_ASSERT(inBuf,
"incorrect size or no data in packet");
1241 if (inBufSize > 0 && inBuf || mCodec->getAVCodec()->capabilities & AV_CODEC_CAP_DELAY)
1244 av_init_packet(&pkt);
1249 VS_LOG_TRACE(
"Attempting decodeVideo(%p, %p, %d, %p, %d);",
1255 if (packet && packet->getAVPacket())
1256 pkt = *packet->getAVPacket();
1258 pkt.size = inBufSize;
1261 retval = avcodec_decode_video2(mCodecContext, avFrame, &frameFinished,
1263 VS_LOG_TRACE(
"Finished %d decodeVideo(%p, %p, %d, %p, %d);",
1279 avFrame->hw_frames_ctx = mCodecContext->hw_frames_ctx;
1280 frame->
copyAVFrame(avFrame, getPixelType(), getWidth(), getHeight());
1282 timeBase = this->mStream ? this->mStream->getTimeBase() : 0;
1284 timeBase = this->getTimeBase();
1286 int64_t packetTs = avFrame->best_effort_timestamp;
1288 if (packetTs != Global::NO_PTS)
1290 if (timeBase->getNumerator() != 0)
1293 int64_t nextPts = mFakePtsTimeBase->rescale(packetTs,
1311 mFakeNextPts = nextPts;
1316 mFakeCurrPts = mFakeNextPts;
1317 double frameDelay = av_rescale(timeBase->getNumerator(),
1318 AV_TIME_BASE, timeBase->getDenominator());
1319 frameDelay += avFrame->repeat_pict * (frameDelay * 0.5);
1322 mFakeNextPts += (int64_t) frameDelay;
1332 frame->
setComplete(frameFinished, this->getPixelType(),
1333 this->getWidth(), this->getHeight(), mFakeCurrPts);
1337 av_frame_free(&avFrame);
1345 int32_t suggestedBufferSize)
1347 int32_t retval = -1;
1357 if (getCodecType() != ICodec::CODEC_TYPE_VIDEO)
1358 throw std::runtime_error(
1359 "Attempting to encode video with non video coder");
1361 if (frame && frame->
getPixelType() != this->getPixelType())
1362 throw std::runtime_error(
1363 "picture is not of the same PixelType as this Coder expected");
1364 if (frame && frame->
getWidth() != this->getWidth())
1365 throw std::runtime_error(
"picture is not of the same width as this Coder");
1366 if (frame && frame->
getHeight() != this->getHeight())
1367 throw std::runtime_error(
1368 "picture is not of the same height as this Coder");
1370 if (mDirection != ENCODING)
1371 throw std::runtime_error(
"Decoding StreamCoder not valid for encoding");
1373 throw std::runtime_error(
"Codec not set");
1374 if (!mCodec->canEncode())
1375 throw std::runtime_error(
"Codec cannot be used to encode");
1376 if (mCodecContext && mOpened && mDirection == ENCODING && packet)
1382 if (suggestedBufferSize <= 0)
1386 suggestedBufferSize = frame->
getSize();
1390 suggestedBufferSize = av_image_get_buffer_size(
1391 (AVPixelFormat) getPixelType(), getWidth(), getHeight(), 1);
1394 VS_ASSERT(suggestedBufferSize> 0,
"no buffer size in input frame");
1395 suggestedBufferSize = FFMAX(suggestedBufferSize, AV_INPUT_BUFFER_MIN_SIZE);
1400 encodingBuffer = packet->
getData();
1404 buf = (uint8_t*) encodingBuffer->getBytes(0, suggestedBufferSize);
1405 bufLen = encodingBuffer->getBufferSize();
1408 if (buf && bufLen || mCodec->getAVCodec()->capabilities & AV_CODEC_CAP_DELAY)
1424 AVFrame* avFrame = 0;
1425 bool dropFrame =
false;
1428 avFrame = av_frame_alloc();
1430 throw std::bad_alloc();
1435 int64_t codecTimeBasePts = thisTimeBase->rescale(frame->
getPts(),
1436 mFakePtsTimeBase.value(), IRational::ROUND_DOWN);
1437 if (mLastPtsEncoded != Global::NO_PTS)
1441 if (codecTimeBasePts < mLastPtsEncoded)
1444 "Dropping frame with timestamp %lld (if coder supports higher time-base use that instead)",
1448 else if (codecTimeBasePts == mLastPtsEncoded)
1454 VS_LOG_TRACE(
"Rescaling ts: %lld to %lld (last: %lld) (from base %d/%d to %d/%d)",
1458 mFakePtsTimeBase->getNumerator(),
1459 mFakePtsTimeBase->getDenominator(),
1460 thisTimeBase->getNumerator(),
1461 thisTimeBase->getDenominator());
1462 avFrame->pts = codecTimeBasePts;
1464 mLastPtsEncoded = avFrame->pts;
1471 VS_LOG_TRACE(
"Attempting encodeVideo(%p, %p, %d, %p)",
1476 packet->getAVPacket()->size = suggestedBufferSize;
1477 retval = avcodec_encode_video2(mCodecContext, packet->getAVPacket(), avFrame, &got_pkt);
1483 ++mNumDroppedFrames;
1488 int64_t dts = (avFrame ? mLastPtsEncoded : mLastPtsEncoded + 1);
1489 int64_t duration = 1;
1491 int32_t num = thisTimeBase->getNumerator();
1492 int32_t den = thisTimeBase->getDenominator();
1493 if (num*1000LL > den)
1495 if (mCodecContext->coded_frame
1496 && mCodecContext->coded_frame->repeat_pict)
1498 num = num * (1+mCodecContext->coded_frame->repeat_pict);
1501 duration = av_rescale(1,
1502 num * (int64_t)den * mCodecContext->ticks_per_frame,
1503 den * (int64_t) thisTimeBase->getNumerator());
1508 int32_t delay = FFMAX(mCodecContext->has_b_frames,
1509 mCodecContext->max_b_frames > 0);
1510 dts = packet->getAVPacket()->dts;
1511 if (packet->getAVPacket()->pts != Global::NO_PTS && dts == Global::NO_PTS && delay <= MAX_REORDER_DELAY)
1513 int64_t pts = packet->getAVPacket()->pts;
1514 mPtsBuffer[0] = pts;
1519 for(i = 1; i < delay + 1 && mPtsBuffer[i] == Global::NO_PTS; i++)
1520 mPtsBuffer[i] = pts + (i-delay-1)*duration;
1523 for(i = 0; i < delay && mPtsBuffer[i] > mPtsBuffer[i+1]; i++)
1524 FFSWAP(int64_t, mPtsBuffer[i], mPtsBuffer[i+1]);
1525 dts = mPtsBuffer[0];
1532 setPacketParameters(
1534 got_pkt ? packet->getAVPacket()->size : retval,
1538 thisTimeBase.
value(),
1539 (packet->getAVPacket()->flags & AV_PKT_FLAG_KEY), duration, got_pkt);
1547 VS_LOG_WARN(
"Attempting to encode when not ready");
1550 catch (std::bad_alloc & e)
1555 catch (std::exception & e)
1557 VS_LOG_WARN(
"Got error: %s", e.what());
1566 int32_t startingSample)
1568 int32_t retval = -1;
1572 bool usingInternalFrameBuffer =
false;
1576 if (mDirection != ENCODING)
1577 throw std::runtime_error(
"Decoding StreamCoder not valid for encoding");
1579 throw std::runtime_error(
"Codec not set");
1580 if (!mCodec->canEncode()) {
1581 std::string msg =
"Codec cannot be used to encode: ";
1582 msg += mCodec->getName();
1583 throw std::runtime_error(msg);
1586 throw std::invalid_argument(
"Invalid packet to encode to");
1591 throw std::runtime_error(
"StreamCoder not initialized properly");
1593 throw std::runtime_error(
"StreamCoder not open");
1594 if (getCodecType() != ICodec::CODEC_TYPE_AUDIO)
1595 throw std::runtime_error(
1596 "Attempting to encode audio with non audio coder");
1597 if (!mAudioFrameBuffer)
1598 throw std::runtime_error(
"Audio Frame Buffer not initialized");
1601 int32_t frameSize = 0;
1602 int32_t frameBytes = 0;
1603 int32_t availableSamples = (samples ? samples->
getNumSamples()
1604 - startingSample : 0);
1605 int32_t samplesConsumed = 0;
1606 short *avSamples = (samples ? samples->getRawSamples(startingSample) : 0);
1611 throw std::invalid_argument(
1612 "channels in sample do not match StreamCoder");
1614 throw std::invalid_argument(
1615 "sample rate in sample does not match StreamCoder");
1618 throw std::invalid_argument(
"input samples are not complete");
1620 if (mFakeNextPts == Global::NO_PTS && samples->
getTimeStamp()
1623 + IAudioSamples::samplesToDefaultPts(startingSample,
1628 if (mFakeNextPts == Global::NO_PTS)
1631 if (availableSamples < 0 || (avSamples && availableSamples == 0))
1632 throw std::invalid_argument(
1633 "no bytes in buffer at specified starting sample");
1635 int32_t bytesPerSample = (samples ? samples->
getSampleSize()
1636 : IAudioSamples::findSampleBitDepth(
1637 (IAudioSamples::FMT_S16)) / 8
1659 frameSize = getAudioFrameSize();
1660 frameBytes = frameSize * bytesPerSample;
1663 VS_ASSERT(frameBytes <= mAudioFrameBuffer->getBufferSize(),
1664 "did frameSize change from open?");
1665 if (frameBytes > mAudioFrameBuffer->getBufferSize())
1666 throw std::runtime_error(
"not enough memory in internal frame buffer");
1668 VS_ASSERT(mBytesInFrameBuffer <= frameBytes,
1669 "did frameSize change from open?");
1670 if (frameBytes < mBytesInFrameBuffer)
1671 throw std::runtime_error(
1672 "too many bytes left over in internal frame buffer");
1674 uint8_t * frameBuffer = (uint8_t*) mAudioFrameBuffer->getBytes(
1677 throw std::runtime_error(
"could not get internal frame buffer");
1679 int32_t bytesToCopyToFrameBuffer = frameBytes - mBytesInFrameBuffer;
1680 bytesToCopyToFrameBuffer = FFMIN(bytesToCopyToFrameBuffer,
1681 availableSamples*bytesPerSample);
1683 uint8_t *convertAvSamples;
1687 if (availableSamples >= frameSize && mBytesInFrameBuffer == 0)
1689 VS_LOG_TRACE(
"audioEncode: Using passed in buffer: %d, %d, %d",
1690 availableSamples, frameSize, mBytesInFrameBuffer);
1691 frameBuffer = (uint8_t*)avSamples;
1692 samplesConsumed = frameSize;
1693 usingInternalFrameBuffer =
false;
1697 VS_LOG_TRACE(
"audioEncode: Using internal buffer: %d, %d, %d %d %d",
1698 availableSamples, frameSize, mBytesInFrameBuffer);
1699 if (bytesToCopyToFrameBuffer != 0){
1700 memcpy(frameBuffer + mBytesInFrameBuffer, avSamples, bytesToCopyToFrameBuffer);
1701 mBytesInFrameBuffer += bytesToCopyToFrameBuffer;
1703 samplesConsumed = bytesToCopyToFrameBuffer / bytesPerSample;
1704 retval = samplesConsumed;
1705 usingInternalFrameBuffer =
true;
1709 if (mPtsOfFrameBuffer == Global::NO_PTS) {
1711 mPtsOfFrameBuffer = thisTimeBase->rescale(samples->
getTimeStamp() + IAudioSamples::samplesToDefaultPts(startingSample, samples->
getSampleRate()), mFakePtsTimeBase.value());
1723 mSamplesForEncoding += samplesConsumed;
1724 VS_LOG_TRACE(
"Consumed %ld for total of %lld Need %d got %d",
1725 samplesConsumed, mSamplesForEncoding, frameBytes, mBytesInFrameBuffer);
1727 if (!frameBuffer || !usingInternalFrameBuffer || mBytesInFrameBuffer
1731 int32_t bufferSize = frameBytes;
1732 if (mCodecContext->codec->id == AV_CODEC_ID_FLAC
1733 || mCodecContext->codec->id == AV_CODEC_ID_VORBIS)
1739 bufferSize = (64 + getAudioFrameSize() * (bytesPerSample + 1)) * 2;
1741 VS_ASSERT(bufferSize> 0,
"no buffer size in samples");
1745 encodingBuffer = packet->
getData();
1752 buf = (uint8_t*) encodingBuffer->getBytes(0, bufferSize);
1754 if (buf && bufferSize)
1756 VS_LOG_TRACE(
"Attempting encodeAudio(%p, %p, %d, %p)",
1803 av_init_packet(&pkt);
1808 retval = avcodec_encode_audio2(mCodecContext, &pkt, NULL, &got_packet);
1811 if (!swr_is_initialized(swrContext)){
1812 swr_alloc_set_opts(swrContext,
1813 (int64_t)samples->getChannelLayout(),
1814 mCodecContext->sample_fmt,
1816 (int64_t)samples->getChannelLayout(),
1821 swr_init(swrContext);
1825 AVFrame* codingFrame = av_frame_alloc();
1826 codingFrame->nb_samples = frameSize;
1827 codingFrame->format = mCodecContext->sample_fmt;
1828 codingFrame->channel_layout = (uint64_t)samples->getChannelLayout();
1830 if (samples->
getPts() != Global::NO_PTS) {
1831 codingFrame->pts = mPtsOfFrameBuffer;
1836 retval = av_frame_get_buffer(codingFrame, 0);
1838 printf(
"Error %s",Error::make(retval)->getDescription());
1839 av_frame_free(&codingFrame);
1840 throw std::bad_alloc();
1843 ret = swr_convert(swrContext, codingFrame->extended_data, frameSize, (
const uint8_t**) &frameBuffer, frameSize);
1845 VS_LOG_ERROR(
"fail to convert samples: %s", Error::make(ret)->getDescription());
1846 av_freep(&convertAvSamples);
1847 throw std::runtime_error(
"fail to convert samples");
1849 VS_LOG_TRACE(
"Finished %d convertAudio(%p, %d, %d, %d, %d, %d);",
1852 availableSamples > frameSize ? frameSize : availableSamples,
1856 retval = avcodec_encode_audio2(mCodecContext, &pkt, codingFrame, &got_packet);
1857 av_frame_free(&codingFrame);
1860 if (retval>=0 && got_packet){
1861 packet->wrapAVPacket(&pkt);
1863 av_packet_unref(&pkt);
1866 VS_LOG_TRACE(
"Finished %d %d encodeAudio(%d, %p, %d, %d, %p)",
1877 mBytesInFrameBuffer = 0;
1878 mPtsOfFrameBuffer = Global::NO_PTS;
1882 if (retval >= 0 && got_packet)
1885 mSamplesCoded += frameSize;
1893 mFakeCurrPts = mFakeNextPts;
1894 if (samples && samples->
getTimeStamp() != Global::NO_PTS)
1897 + IAudioSamples::samplesToDefaultPts(startingSample
1898 + samplesConsumed, getSampleRate());
1899 int64_t samplesCached = mSamplesForEncoding - mSamplesCoded;
1900 int64_t tsDelta = IAudioSamples::samplesToDefaultPts(
1901 samplesCached, getSampleRate());
1902 int64_t gap = samplesTs - (mFakeNextPts + tsDelta);
1909 VS_LOG_TRACE(
"reset;"
1911 "samplesConsumed:%ld;"
1912 "startingSample:%lu;"
1913 "samplesForEncoding:%lld;"
1914 "samplesCoded:%lld;"
1915 "samplesCached:%lld;"
1919 "lastExternallySetTs:%lld;"
1920 "new fakeNextPts:%lld;",
1924 mSamplesForEncoding,
1930 mLastExternallySetTimeStamp,
1931 samplesTs - tsDelta);
1932 mLastExternallySetTimeStamp = samplesTs - tsDelta;
1934 mSamplesForEncoding = samplesCached;
1937 mFakeNextPts = mLastExternallySetTimeStamp
1938 + IAudioSamples::samplesToDefaultPts(mSamplesCoded,
1944 int64_t duration = IAudioSamples::samplesToDefaultPts(frameSize,
1948 thisTimeBase.
reset(mFakePtsTimeBase.value(),
true);
1953 ts = thisTimeBase->rescale(mFakeCurrPts, mFakePtsTimeBase.value());
1955 = thisTimeBase->rescale(duration, mFakePtsTimeBase.value());
1957 setPacketParameters(packet, size, ts, thisTimeBase.
value(),
true,
1958 duration, got_packet);
1963 retval = samplesConsumed;
1967 throw std::runtime_error(
"avcodec_encode_audio failed");
1972 catch (std::bad_alloc & e)
1976 catch (std::exception& e)
1978 VS_LOG_WARN(
"error: %s", e.what());
1986 StreamCoder::setPacketParameters(
Packet * packet, int32_t size, int64_t dts,
1987 IRational *timebase,
bool keyframe, int64_t duration,
bool complete)
1998 if (packet->getAVPacket()->pts != Global::NO_PTS)
2001 pts = timebase->
rescale(packet->getAVPacket()->pts, coderBase.
value());
2003 if (pts == Global::NO_PTS)
2006 if (pts != Global::NO_PTS && (dts == Global::NO_PTS || dts > pts))
2027 if (mAutomaticallyStampPacketsForStream)
2028 mStream->stampOutputPacket(packet);
2031 VS_LOG_TRACE(
"Encoded packet; size: %d; pts: %lld", size, pts);
2035 StreamCoder::getAudioFrameSize()
2038 if (mCodec && mCodec->getType() == ICodec::CODEC_TYPE_AUDIO)
2040 if (mCodecContext->frame_size <= 1)
2044 retval = getDefaultAudioFrameSize();
2048 retval = mCodecContext->frame_size;
2055 StreamCoder::streamClosed(
Stream*stream)
2058 if (stream == mStream)
2067 StreamCoder::acquire()
2070 retval = RefCounted::acquire();
2071 VS_LOG_TRACE(
"Acquired %p: %d",
this, retval);
2076 StreamCoder::release()
2079 retval = RefCounted::release();
2080 VS_LOG_TRACE(
"Released %p: %d",
this, retval);
2085 StreamCoder::getCodecTag()
2087 return (mCodecContext ? mCodecContext->codec_tag : 0);
2091 StreamCoder::setCodecTag(int32_t tag)
2094 mCodecContext->codec_tag = tag;
2098 StreamCoder::getNumProperties()
2100 return Property::getNumProperties(mCodecContext);
2104 StreamCoder::getPropertyMetaData(int32_t propertyNo)
2106 return Property::getPropertyMetaData(mCodecContext, propertyNo);
2110 StreamCoder::getPropertyMetaData(
const char *name)
2112 return Property::getPropertyMetaData(mCodecContext, name);
2118 return Property::setProperty(mCodecContext, valuesToSet, valuesNotFound);
2123 StreamCoder::setProperty(
const char* aName,
const char *aValue)
2125 return Property::setProperty(mCodecContext, aName, aValue);
2129 StreamCoder::setProperty(
const char* aName,
double aValue)
2131 return Property::setProperty(mCodecContext, aName, aValue);
2135 StreamCoder::setProperty(
const char* aName, int64_t aValue)
2137 return Property::setProperty(mCodecContext, aName, aValue);
2141 StreamCoder::setProperty(
const char* aName,
bool aValue)
2143 return Property::setProperty(mCodecContext, aName, aValue);
2147 StreamCoder::setProperty(
const char* aName,
IRational *aValue)
2149 return Property::setProperty(mCodecContext, aName, aValue);
2153 StreamCoder::getPropertyAsString(
const char *aName)
2155 return Property::getPropertyAsString(mCodecContext, aName);
2159 StreamCoder::getPropertyAsDouble(
const char *aName)
2161 return Property::getPropertyAsDouble(mCodecContext, aName);
2165 StreamCoder::getPropertyAsLong(
const char *aName)
2167 return Property::getPropertyAsLong(mCodecContext, aName);
2171 StreamCoder::getPropertyAsRational(
const char *aName)
2173 return Property::getPropertyAsRational(mCodecContext, aName);
2177 StreamCoder::getPropertyAsBoolean(
const char *aName)
2179 return Property::getPropertyAsBoolean(mCodecContext, aName);
2183 StreamCoder::isOpen()
2189 StreamCoder::getDefaultAudioFrameSize()
2191 return mDefaultAudioFrameSize;
2195 StreamCoder::setDefaultAudioFrameSize(int32_t aNewSize)
2198 mDefaultAudioFrameSize = aNewSize;
2202 StreamCoder::setStream(
Stream* stream,
bool assumeOnlyStream)
2204 int32_t retval = -1;
2205 if (assumeOnlyStream)
2207 AVStream *avStream = stream ? stream->getAVStream() : 0;
2214 if (avStream->codec) {
2215 resetOptions(avStream->codec);
2216 av_freep(&avStream->codec->extradata);
2217 av_freep(&avStream->codec->subtitle_header);
2218 avcodec_free_context(&avStream->codec);
2220 avStream->codec = mCodecContext;
2227 StreamCoder::getNumDroppedFrames()
2229 return mNumDroppedFrames;
2233 StreamCoder::setAutomaticallyStampPacketsForStream(
bool value)
2236 mAutomaticallyStampPacketsForStream = value;
2240 StreamCoder::getAutomaticallyStampPacketsForStream()
2242 return mAutomaticallyStampPacketsForStream;
2247 int32_t numBytes,
bool allocNew)
2249 if (!mCodecContext || !src)
2252 void* bytes = src->
getBytes(offset, numBytes);
2256 if (mCodecContext->extradata_size < numBytes || !mCodecContext->extradata)
2260 av_free(mCodecContext->extradata);
2261 mCodecContext->extradata_size = 0;
2262 mCodecContext->extradata = (uint8_t*) av_malloc(numBytes
2263 + AV_INPUT_BUFFER_MIN_SIZE);
2264 if (!mCodecContext->extradata)
2268 mCodecContext->extradata_size = numBytes;
2273 memcpy(mCodecContext->extradata, bytes, numBytes);
2276 avcodec_parameters_from_context(mStream->getAVStream()->codecpar, mCodecContext);
2282 int32_t maxBytesToCopy)
2284 if (!mCodecContext || !mCodecContext->extradata
2285 || mCodecContext->extradata_size <= 0 || !dest || offset < 0
2286 || maxBytesToCopy < 0 || dest->getSize() < offset + maxBytesToCopy)
2289 int32_t bytesToCopy = FFMIN(maxBytesToCopy, mCodecContext->extradata_size);
2290 if (bytesToCopy <= 0)
2292 void* bytes = dest->
getBytes(offset, bytesToCopy);
2295 memcpy(bytes, mCodecContext->extradata, bytesToCopy);
2300 StreamCoder::getExtraDataSize()
2303 return mCodecContext->extradata_size;
2308 StreamCoder :: getStandardsCompliance()
2320 mCodecContext->strict_std_compliance = compliance;
2327 if (!(av_pix_fmt_desc_get((AVPixelFormat)type)->flags & AV_PIX_FMT_FLAG_HWACCEL)) {
2328 VS_LOG_WARN(
"Requested type is not hardware accelerated, default decoder will be used instead %d %d", av_pix_fmt_desc_get((AVPixelFormat)type)->flags, AV_PIX_FMT_FLAG_HWACCEL);
2332 if (mCodecContext && mStream) {
2333 AVBufferRef* device_ctx = NULL;
2334 Codec* codec = Codec::findDecodingCodec(mCodec->getID(), type);
2336 VS_LOG_WARN(
"No hardware decoder found for requested type, looking for hwaccel");
2337 for (
int i = 0;; i++) {
2338 const AVCodecHWConfig *config = avcodec_get_hw_config(mCodec->getAVCodec(), i);
2340 VS_LOG_WARN(
"Decoder %s does not support any device type",
2341 mCodec->getAVCodec()->name);
2344 if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX &&
2345 config->pix_fmt == (AVPixelFormat)type) {
2346 if (av_hwdevice_ctx_create(&device_ctx, config->device_type, NULL, NULL, 0) < 0) {
2347 VS_LOG_WARN(
"Unable to create device for type %s", av_hwdevice_get_type_name(config->device_type));
2350 mCodecContext->hw_device_ctx = av_buffer_ref(device_ctx);
2355 VS_LOG_WARN(
"No hardware decoder found for requested type, default decoder will be used instead");
2360 avcodec_free_context(&mCodecContext);
2361 mCodecContext = avcodec_alloc_context3(codec->getAVCodec());
2363 if (avcodec_parameters_to_context(mCodecContext, mStream->getAVStream()->codecpar) < 0)
2364 throw std::runtime_error(
"could not initialize codec");
2367 readyAVContexts(mDirection,
2374 if (type == IPixelFormat::MEDIACODEC) {
2376 if (!mCodecContext->hwaccel_context && surface){
2377 jobject jSurface =
static_cast<jobject
>(surface);
2379 mediacodec_alloc_context(mCodecContext, JNIHelper::sGetEnv(), jSurface);
2384 VS_LOG_WARN(
"Try to use MediaCodec Android hardware type on non Android platform");
2387 VS_LOG_WARN(
"Hardware context not yet supported %s", mCodecContext->hwaccel->name);
2390 VS_LOG_WARN(
"try to set HW decoding on uninitialized AVContext or AVStream");
2396 StreamCoder::getHardwareSurface()
2399 return mediacodec_create_input_surface(mCodecContext, JNIHelper::sGetEnv());
2401 VS_LOG_WARN(
"Hardware surface not yet supported");
virtual int32_t getSampleSize()
virtual int32_t getSampleRate()
Find the sample rate of the samples in this audio buffer.
virtual int64_t getTimeStamp()
Get the time stamp of this object in getTimeBase() units.
virtual int32_t getChannels()
Return the number of channels of the samples in this buffer.
virtual int32_t ensureCapacity(int32_t capacityInBytes)
Called by decoder before decoding to ensure sufficient space.
virtual void setComplete(bool complete, int32_t numSamples, int32_t sampleRate, int32_t channels, Format sampleFmt, int64_t pts)
Call this if you modify the samples and are now done.
virtual int64_t getPts()
What is the Presentation Time Stamp of this set of audio samples.
virtual int32_t getMaxBufferSize()
virtual int32_t getNumSamples()
Get the number of samples in this video.
virtual bool isComplete()
Returns whether or not we think this buffer has been filled with data.
A set of raw (decoded) samples, plus a timestamp for when to play those samples relative to other ite...
Format
The format we use to represent audio.
A "key" to an IStreamCoder that tells it how to encode or decode data.
ID
These are the codecs this library currently supports.
Type
The different types of Codecs that can exist in the system.
Represents an encoded piece of data that can be placed in an IContainer for a given IStream of data.
Represents settable properties that effect how AVPKit objects operate.
This class wraps represents a Rational number for the AVPKit.
virtual int64_t rescale(int64_t origValue, IRational *origBase)=0
Takes a value scaled in increments of origBase and gives the equivalent value scaled in terms of this...
virtual int32_t getDenominator()=0
Get the denominator for this rational.
virtual int32_t getNumerator()=0
Get the numerator for this rational.
CodecStandardsCompliance
An enumeration of how strictly Codecs may follow the spec.
Flags
AVPKIT Flags that can be passed to the setFlag(Flags, bool) method.
Direction
The Direction in which this StreamCoder will work.
Represents a stream of similar data (eg video) in a IContainer.
Represents one raw (undecoded) picture in a video stream, plus a timestamp for when to display that v...
virtual int32_t allocateNewPayload(int32_t payloadSize)
Discard the current payload and allocate a new payload.
virtual int64_t getPts()
Get the Presentation Time Stamp (PTS) for this packet.
virtual void setKeyPacket(bool keyPacket)
Set if this is a key packet.
virtual void setDuration(int64_t duration)
Set the duration.
virtual com::avpkit::ferry::IBuffer * getData()
Get any underlying raw data available for this object.
virtual void setStreamIndex(int32_t streamIndex)
Set the stream index for this packet.
virtual void reset()
Clear out any data in this packet, but leaves the buffer available for reuse.
virtual int32_t getSize()
Get the size in bytes of the payload currently in this packet.
virtual void setPts(int64_t pts)
Set a new Presentation Time Stamp (PTS) for this packet.
virtual void setDts(int64_t dts)
Set a new Decompression Time Stamp (DTS) for this packet.
virtual void setComplete(bool complete, int32_t size)
Set if this packet is complete, and what the total size of the data should be assumed to be.
virtual void setTimeBase(IRational *aBase)
Set the time base that time stamps of this object are represented in.
virtual void setComplete(bool aIsComplete, IPixelFormat::Type format, int width, int height, int64_t pts)
After modifying the raw data in this buffer, call this function to let the object know it is now comp...
virtual int64_t getPts()
What is the Presentation Time Stamp (in Microseconds) of this picture.
virtual IPixelFormat::Type getPixelType()
Returns the pixel format of the picture.
virtual int32_t getSize()
Total size in bytes of the decoded picture.
void copyAVFrame(AVFrame *frame, IPixelFormat::Type pixel, int32_t width, int32_t height)
Called by the StreamCoder once it's done decoding.
void fillAVFrame(AVFrame *frame)
Called by the StreamCoder before it encodes a picture.
virtual int getWidth()
What is the width of the picture.
virtual int getHeight()
What is the height of the picture.
Allows Java code to get data from a native buffers, and optionally modify native memory directly.
virtual void * getBytes(int32_t offset, int32_t length)=0
Returns up to length bytes, starting at offset in the underlying buffer we're managing.
This class is only useful from C++.
T * value()
Return the managed pointer without calling RefCounted::acquire() on it.
void reset(T *ptr=0, bool acquire=false)
Reset the managed pointer, calling RefCounted::release() on the previously managed pointer first.
This library contains routines used by AVPKit libraries for "ferry"ing Java objects to and from nativ...
WARNING: Do not use logging in this class, and do not set any static file variables to values other t...