[FFmpeg-devel] [PATCH 1/2] examples: demuxing: do partial audio packet decoding
Stefano Sabatini
stefasab at gmail.com
Sun Jul 14 11:43:46 CEST 2013
On date Saturday 2013-07-13 15:53:19 +0200, wm4 encoded:
> This assumes one audio packet is decoded one time. This is not true:
> packets can be partially decoded. Then you have to "adjust" the packet
> and pass the undecoded part of the packet to the decode function again.
> ---
> doc/examples/demuxing.c | 19 ++++++++++++++++---
> 1 file changed, 16 insertions(+), 3 deletions(-)
>
> diff --git a/doc/examples/demuxing.c b/doc/examples/demuxing.c
> index 8a1b69b..1c0f1ff 100644
> --- a/doc/examples/demuxing.c
> +++ b/doc/examples/demuxing.c
> @@ -60,6 +60,7 @@ static int audio_frame_count = 0;
> static int decode_packet(int *got_frame, int cached)
> {
> int ret = 0;
> + int decoded = pkt.size;
After re-reading the docs, avcodec_decode_video2 should return the
consumed bytes as well, so we can assume that ret will contain
pkt.size after decoding.
>
> if (pkt.stream_index == video_stream_idx) {
> /* decode video frame */
> @@ -91,6 +92,11 @@ static int decode_packet(int *got_frame, int cached)
> fprintf(stderr, "Error decoding audio frame\n");
> return ret;
> }
> + /* Some audio decoders decode only part of the packet, and have to be
> + * called again with the remainder of the packet data.
> + * Sample: fate-suite/lossless-audio/luckynight-partial.shn
> + * Also, some decoders might over-read the packet. */
> + decoded = FFMIN(ret, pkt.size);
What decoders? This sounds as a bug, not something to band-aid in the
application code.
Also, even in this case the external check on pkt.size > 0 should work
fine.
>
> if (*got_frame) {
> printf("audio_frame%s n:%d nb_samples:%d pts:%s\n",
> @@ -121,7 +127,7 @@ static int decode_packet(int *got_frame, int cached)
> }
> }
>
> - return ret;
> + return decoded;
> }
>
> static int open_codec_context(int *stream_idx,
> @@ -293,8 +299,15 @@ int main (int argc, char **argv)
>
> /* read frames from the file */
> while (av_read_frame(fmt_ctx, &pkt) >= 0) {
> - decode_packet(&got_frame, 0);
> - av_free_packet(&pkt);
> + AVPacket orig_pkt = pkt;
> + do {
> + ret = decode_packet(&got_frame, 0);
> + if (ret < 0)
> + break;
> + pkt.data += ret;
> + pkt.size -= ret;
> + } while (pkt.size > 0);
> + av_free_packet(&orig_pkt);
> }
>
> /* flush cached frames */
This looks good.
--
FFmpeg = Fantastic and Forgiving Mortal Pitiful Encoding/decoding Gorilla
More information about the ffmpeg-devel
mailing list