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;
            }
Esempio n. 2
0
/**
 * 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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
/**
 * 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;
}