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; }
/* ================= 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 ); }
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; }
/* 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, ¶m); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "MFX decode get param error %d\n", ret); } ret = MFXVideoDECODE_Reset(q->session, ¶m); 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; }
/* ================================================================= 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; }
/* ================= 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; }
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); }