Beispiel #1
0
int ff_qsv_decode(AVCodecContext *avctx, QSVContext *q,
                  AVFrame *frame, int *got_frame,
                  AVPacket *avpkt)
{
    AVPacket pkt_ref = { 0 };
    int ret = 0;

    if (q->pkt_fifo && av_fifo_size(q->pkt_fifo) >= sizeof(AVPacket)) {
        /* we already have got some buffered packets. so add new to tail */
        ret = av_packet_ref(&pkt_ref, avpkt);
        if (ret < 0)
            return ret;
        av_fifo_generic_write(q->pkt_fifo, &pkt_ref, sizeof(pkt_ref), NULL);
    }
    if (q->reinit_pending) {
        ret = do_qsv_decode(avctx, q, frame, got_frame, avpkt);

        if (!*got_frame) {
            /* Flushing complete, no more frames  */
            close_decoder(q);
            //return ff_qsv_decode(avctx, q, frame, got_frame, avpkt);
        }
    }
    if (!q->reinit_pending) {
        if (q->pkt_fifo && av_fifo_size(q->pkt_fifo) >= sizeof(AVPacket)) {
            /* process buffered packets */
            while (!*got_frame && av_fifo_size(q->pkt_fifo) >= sizeof(AVPacket)) {
                av_fifo_generic_read(q->pkt_fifo, &pkt_ref, sizeof(pkt_ref), NULL);
                ret = do_qsv_decode(avctx, q, frame, got_frame, &pkt_ref);
                if (q->reinit_pending) {
                    /*
                       A rare case: new reinit pending when buffering existing.
                       We should to return the pkt_ref back to same place of fifo
                    */
                    qsv_packet_push_front(q, &pkt_ref);
                } else {
                    av_packet_unref(&pkt_ref);
                }
           }
        } else {
            /* general decoding */
            ret = do_qsv_decode(avctx, q, frame, got_frame, avpkt);
            if (q->reinit_pending) {
                ret = av_packet_ref(&pkt_ref, avpkt);
                if (ret < 0)
                    return ret;
                av_fifo_generic_write(q->pkt_fifo, &pkt_ref, sizeof(pkt_ref), NULL);
            }
        }
    }

    return ret;
}
Beispiel #2
0
/*
=================
Stream_FreeMPG

assume stream is valid
=================
*/
void Stream_FreeMPG( stream_t *stream )
{
	if( stream->ptr )
	{
		mpeg_t	*mpg;

		mpg = (mpeg_t *)stream->ptr;
		close_decoder( mpg );
		Mem_Free( stream->ptr );
	}

	if( stream->file )
	{
		FS_Close( stream->file );
	}

	Mem_Free( stream );
}
Beispiel #3
0
int ff_qsv_decode_close(QSVContext *q)
{
    close_decoder(q);

    q->session = NULL;

    ff_qsv_close_internal_session(&q->internal_qs);

    av_fifo_free(q->async_fifo);
    q->async_fifo = NULL;

    av_fifo_free(q->input_fifo);
    q->input_fifo = NULL;

    av_fifo_free(q->pkt_fifo);
    q->pkt_fifo = NULL;

    return 0;
}
Beispiel #4
0
/*
 This function resets decoder and corresponded buffers before seek operation
*/
void ff_qsv_decode_reset(AVCodecContext *avctx, QSVContext *q)
{
    QSVFrame *cur;
    AVPacket pkt;
    int ret = 0;
    mfxVideoParam param = { { 0 } };

    if (q->reinit_pending) {
        close_decoder(q);
    } else if (q->engine_ready) {
        ret = MFXVideoDECODE_GetVideoParam(q->session, &param);
        if (ret < 0) {
            av_log(avctx, AV_LOG_ERROR, "MFX decode get param error %d\n", ret);
        }

        ret = MFXVideoDECODE_Reset(q->session, &param);
        if (ret < 0) {
            av_log(avctx, AV_LOG_ERROR, "MFX decode reset error %d\n", ret);
        }

        /* Free all frames*/
        cur = q->work_frames;
        while (cur) {
            q->work_frames = cur->next;
            av_frame_free(&cur->frame);
            av_freep(&cur);
            cur = q->work_frames;
        }
    }

    /* Reset output surfaces */
    av_fifo_reset(q->async_fifo);

    /* Reset input packets fifo */
    while (av_fifo_size(q->pkt_fifo)) {
        av_fifo_generic_read(q->pkt_fifo, &pkt, sizeof(pkt), NULL);
        av_packet_unref(&pkt);
    }

    /* Reset input bitstream fifo */
    av_fifo_reset(q->input_fifo);
}
int main(void)
{
    AVCodec *enc = NULL, *dec = NULL;
    AVCodecContext *enc_ctx = NULL, *dec_ctx = NULL;
    uint64_t channel_layouts[] = {AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_5POINT1_BACK, AV_CH_LAYOUT_SURROUND, AV_CH_LAYOUT_STEREO_DOWNMIX};
    int sample_rates[] = {8000, 44100, 48000, 192000};
    int cl, sr;

    avcodec_register_all();

    enc = avcodec_find_encoder(AV_CODEC_ID_FLAC);
    if (!enc)
    {
        av_log(NULL, AV_LOG_ERROR, "Can't find encoder\n");
        return 1;
    }

    dec = avcodec_find_decoder(AV_CODEC_ID_FLAC);
    if (!dec)
    {
        av_log(NULL, AV_LOG_ERROR, "Can't find decoder\n");
        return 1;
    }

    for (cl = 0; cl < FF_ARRAY_ELEMS(channel_layouts); cl++)
    {
        for (sr = 0; sr < FF_ARRAY_ELEMS(sample_rates); sr++)
        {
            if (init_encoder(enc, &enc_ctx, channel_layouts[cl], sample_rates[sr]) != 0)
                return 1;
            if (init_decoder(dec, &dec_ctx, channel_layouts[cl]) != 0)
                return 1;
            if (run_test(enc, dec, enc_ctx, dec_ctx) != 0)
                return 1;
            close_encoder(&enc_ctx);
            close_decoder(&dec_ctx);
        }
    }

    return 0;
}
Beispiel #6
0
/*
=================================================================

	MPEG decompression

=================================================================
*/
qboolean Sound_LoadMPG( const char *name, const byte *buffer, size_t filesize )
{
	mpeg_t	mpeg;
	size_t	pos = 0;
	size_t	bytesWrite = 0;

	// load the file
	if( !buffer || filesize < FRAME_SIZE )
		return false;

	// couldn't create decoder
	if( !create_decoder( &mpeg ))
		return false;

	// trying to read header
	if( !read_mpeg_header( &mpeg, buffer, FRAME_SIZE, filesize ))
	{
		MsgDev( D_ERROR, "Sound_LoadMPG: (%s) is probably corrupted\n", name );
		close_decoder( &mpeg );
		return false;
	}

	sound.channels = mpeg.channels;
	sound.rate = mpeg.rate;
	sound.width = 2; // always 16-bit PCM
	sound.loopstart = -1;
	sound.size = ( sound.channels * sound.rate * sound.width ) * ( mpeg.play_time / 1000 ); // in bytes
	pos += FRAME_SIZE;	// evaluate pos

	if( !sound.size )
	{
		// bad mpeg file ?
		MsgDev( D_ERROR, "Sound_LoadMPG: (%s) is probably corrupted\n", name );
		close_decoder( &mpeg );
		return false;
	}

	sound.type = WF_PCMDATA;
	sound.wav = (byte *)Mem_Alloc( host.soundpool, sound.size );

	// decompress mpg into pcm wav format
	while( bytesWrite < sound.size )
	{
		int	outsize;

		if( read_mpeg_stream( &mpeg, NULL, 0 ) != MP3_OK )
		{
			char	*data = (char *)buffer + pos;
			int	bufsize;

			// if there are no bytes remainig so we can decompress the new frame
			if( pos + FRAME_SIZE > filesize )
				bufsize = ( filesize - pos );
			else bufsize = FRAME_SIZE;
			pos += bufsize;

			if( read_mpeg_stream( &mpeg, data, bufsize ) != MP3_OK )
				break; // there was end of the stream
		}

		if( bytesWrite + mpeg.outsize > sound.size )
			outsize = ( sound.size - bytesWrite );
		else outsize = mpeg.outsize;

		Q_memcpy( &sound.wav[bytesWrite], mpeg.out, outsize );
		bytesWrite += outsize;
	}

	sound.samples = bytesWrite / ( sound.width * sound.channels );
	close_decoder( &mpeg );

	return true;
}
Beispiel #7
0
/*
=================
Stream_OpenMPG
=================
*/
stream_t *Stream_OpenMPG( const char *filename )
{
	mpeg_t	*mpegFile;
	stream_t	*stream;
	file_t	*file;
	long	filesize, read_len;
	char	tempbuff[FRAME_SIZE];

	file = FS_Open( filename, "rb", false );
	if( !file ) return NULL;

	filesize = FS_FileLength( file );
	if( filesize < FRAME_SIZE )
	{
		MsgDev( D_ERROR, "Stream_OpenMPG: %s is probably corrupted\n", filename );
		FS_Close( file );
		return NULL;
	}

	// at this point we have valid stream
	stream = Mem_Alloc( host.soundpool, sizeof( stream_t ));
	stream->file = file;
	stream->pos = 0;

	mpegFile = Mem_Alloc( host.soundpool, sizeof( mpeg_t ));

	// couldn't create decoder
	if( !create_decoder( mpegFile ))
	{
		MsgDev( D_ERROR, "Stream_OpenMPG: couldn't create decoder\n" );
		Mem_Free( mpegFile );
		Mem_Free( stream );
		FS_Close( file );
		return NULL;
	}

	read_len = FS_Read( file, tempbuff, sizeof( tempbuff ));
	if( read_len < sizeof( tempbuff ))
	{
		MsgDev( D_ERROR, "Stream_OpenMPG: %s is probably corrupted\n", filename );
		close_decoder( mpegFile );
		Mem_Free( mpegFile );
		Mem_Free( stream );
		FS_Close( file );
		return NULL;
	}

	// trying to read header
	if( !read_mpeg_header( mpegFile, tempbuff, sizeof( tempbuff ), filesize ))
	{
		MsgDev( D_ERROR, "Sound_LoadMPG: (%s) is probably corrupted\n", filename );
		close_decoder( mpegFile );
		Mem_Free( mpegFile );
		Mem_Free( stream );
		FS_Close( file );
		return NULL;
	}

	stream->buffsize = 0; // how many samples left from previous frame
	stream->channels = mpegFile->channels;
	stream->pos += mpegFile->outsize;
	stream->rate = mpegFile->rate;
	stream->width = 2;	// always 16 bit
	stream->ptr = mpegFile;
	stream->type = WF_MPGDATA;

	return stream;
}
Beispiel #8
0
static void split_video(const char *infilename,
                        const char *outfmt,
                        int gop_size,
                        int chunk_size,
                        int skip,
                        long long length,
                        AVDictionary *_opt)
{
    DecoderContext *dc;
    EncoderContext *ec;

    AVFrame *frame;
    int width, height;
    long long frame_count = 0, out_frame_num = 0;
    int chunk_count = 0;
    char outfilename[MAX_FILENAME_LEN];
    AVDictionary *opt = NULL;
    AVRational framerate;
    enum AVPixelFormat pix_fmt;

    av_dict_copy(&opt, _opt, 0);

    // Initialize the decoder
    dc = init_decoder(infilename);

    // Extract parms needed by encoder
    width = dc->codecCtx->width;
    height = dc->codecCtx->height;
    framerate = dc->codecCtx->framerate;
    pix_fmt = dc->codecCtx->pix_fmt;

    // Skip input frames

    if (skip > 0)
        fprintf(stderr, "Skipping %d frames\n", skip);

    while (skip > 0) {
        // TODO: I'd rather not decode the frames, but this will take some work to
        //       refactor
        if (!read_frame(dc)) {
            fprintf(stderr, "No more frames available, skip = %d\n", skip);
            exit(0);
        }
        --skip;
    }

    // Initialize output
    fprintf(stderr, "\rWriting chunk %05d", chunk_count);
    fflush(stderr);

    snprintf(outfilename, MAX_FILENAME_LEN, outfmt, chunk_count++);
    ec = init_encoder(outfilename, gop_size, width, height, framerate, pix_fmt, opt);

    while (length <= 0 || frame_count < length) {
        frame = read_frame(dc);
        if (!frame)
            break;

        if (out_frame_num == chunk_size) {
            close_encoder(ec);

            fprintf(stderr, "\rWriting chunk %05d", chunk_count);
            fflush(stderr);

            snprintf(outfilename, MAX_FILENAME_LEN, outfmt, chunk_count++);
            ec = init_encoder(outfilename, gop_size, width, height, framerate, pix_fmt, opt);
            out_frame_num = 0;
        }

        set_pict_type(frame, gop_size, out_frame_num);
        frame->pts = out_frame_num++;
        frame_count++;

        write_video_frame(ec, frame);
    }

    close_encoder(ec);
    close_decoder(dc);

    fprintf(stderr, "\nRead %lld frames\n", frame_count);
    fprintf(stderr, "Wrote %d chunks of %d frames each (last chunk: %lld frames)\n", chunk_count, chunk_size, out_frame_num);
    fprintf(stderr, "  for a total of %lld frames\n", (chunk_count-1) * chunk_size + out_frame_num);
}