void decodeFrame() throw(PacketDecodeException) { if (!hasPacket()) throw PacketDecodeException(); int dataSize = sampleBufferAlloc; int used = #if (LIBAVCODEC_VERSION_MAJOR >= 53) avcodec_decode_audio3( pCodecCtx, (int16_t*)sampleBufferAligned, &dataSize, &packet); #else avcodec_decode_audio2( pCodecCtx, (int16_t*)sampleBufferAligned, &dataSize, packetBuffer, packetBufferSize); #endif if (used < 0) throw PacketDecodeException(); #if (LIBAVCODEC_VERSION_MAJOR >= 53) if ((size_t)used > packet.size) used = packet.size; (char*&)(packet.data) += used; packet.size -= used; #else if ((size_t)used > packetBufferSize) used = packetBufferSize; (char*&)packetBuffer += used; packetBufferSize -= used; #endif if (dataSize < 0) dataSize = 0; sampleBuffer = sampleBufferAligned; sampleBufferStart += sampleBufferSize; sampleBufferSize = dataSize / sampleSize; if (sampleBufferStart + sampleBufferSize > streamSize) streamSize = sampleBufferStart + sampleBufferSize; }
/** * A callback function that decodes a video packet. This should be supplied * to the <code>decodePacketTemplate</code> template. * * @param codecContext - the codec context that will be used to decode the callback. * @param packet - the packet that is to be decoded. * @return the decoded packet as an AVFrame. */ static AVFrame* decodeVideoPacketCallBack(AVCodecContext *codecContext, AVPacket *packet) { if (AVMEDIA_TYPE_VIDEO != findCodecType(codecContext)) { throw IllegalArgumentException( "The supplied codec context for decodeVideoPacket(AVCodecContext*,AVPacket*) must have media type AVMEDIA_TYPE_VIDEO."); } AVFrame *decodedFrame = avcodec_alloc_frame(); int bytesDecoded = 0; int frameDecoded = 0; bytesDecoded = avcodec_decode_video2(codecContext, decodedFrame, &frameDecoded, packet); if (AVERROR_INVALIDDATA == bytesDecoded) { throw InvalidPacketDataException(errorMessage(bytesDecoded)); } if (0 > bytesDecoded) { throw PacketDecodeException(errorMessage(bytesDecoded)); } if (0 != frameDecoded) return decodedFrame; return NULL; }
static AVPacket* encodeFrameWrapper(AVCodecContext *codecContext, const AVFrame *frame, std::tr1::function<int(AVCodecContext *codecContext, AVPacket *packet, const AVFrame *frame, int *packetEncoded)> encodeCallback) { if (NULL == codecContext) { throw IllegalArgumentException("The codec context for encoding cannot be null."); } if (NULL == frame) { throw IllegalArgumentException("The frame for encoding cannot be null."); } AVPacket *packet = new AVPacket(); packet->size = 0; packet->data = NULL; av_init_packet(packet); int packetEncoded = 0; int result = encodeCallback(codecContext, packet, frame, &packetEncoded); if (AVERROR_INVALIDDATA == result) { throw InvalidPacketDataException(errorMessage(result)); } if (0 > result) { throw PacketDecodeException(errorMessage(result)); } if (0 != packetEncoded) return packet; return NULL; }
/** * A callback function that decodes an audio packet. This should be supplied * to the <code>decodePacketTemplate</code> template. * * @param codecContext - the codec context that will be used to decode the callback. * @param packet - the packet that is to be decoded. * @return the decoded packet as a vector of AVFrames. */ static vector<AVFrame*> decodeAudioPacketCallback(AVCodecContext *codecContext, AVPacket *packet) { if (AVMEDIA_TYPE_AUDIO != findCodecType(codecContext)) { throw IllegalArgumentException( "The supplied codec context for decoding audio must have media type AVMEDIA_TYPE_AUDIO."); } // This vector will contain all the audio frames decoded from the supplied packet. vector<AVFrame*> frames; // The frame pointer that will hold each new frame before it is placed in the vector. AVFrame *decodedFrame = NULL; // This will be set to 1 if a frame has successfully been decoded with the // avcodec_decode_audio4() function. int frameDecoded = 0; int bytesDecoded = 0; // The number of bytes that were decoded in each iteration. while (0 < packet->size) { // Create a new frame to contain the decoded data if one is required. if (NULL == decodedFrame) decodedFrame = avcodec_alloc_frame(); // Decode the packet and store it in the new frame. // Also record how many bytes were decoded because it might not have been all // of them. bytesDecoded = avcodec_decode_audio4(codecContext, decodedFrame, &frameDecoded, packet); // If there is an invalid data error throw a more specific exception. if (AVERROR_INVALIDDATA == bytesDecoded) { throw InvalidPacketDataException(errorMessage(bytesDecoded)); } if (0 > bytesDecoded) { throw PacketDecodeException(errorMessage(bytesDecoded)); } // If a frame was successfully decoded add it the vector to be returned and // set the pointer to null to indicate we need a new frame allocated. if (0 != frameDecoded) { frames.push_back(decodedFrame); decodedFrame = NULL; } else { // If we haven't successfully decoded a frame reset the decode frame // values to make sure it's ready for another decode attempt. avcodec_get_frame_defaults(decodedFrame); } // Push the data pointer down the byte array passed the last byte that we // decoded. packet->data += bytesDecoded; // Reduce the relative size of the data to the amount that is yet to be // decoded. packet->size -= bytesDecoded; } return frames; }