[Libav-user] 回复: 回复: just wanna get a decode demo for libav

Steven Liu lingjiujianke at gmail.com
Sat May 13 01:44:22 EEST 2017


2017-05-13 0:05 GMT+08:00 Steven Liu <lingjiujianke at gmail.com>:

>
>
> 2017-05-12 21:53 GMT+08:00 坚定前行 <powerpan at qq.com>:
>
>> Hi,
>>
>> thanks for the reply but your answer didn't help. first of all, i need to
>> register a codec and open it automatically, but decode_audio.c did not show
>> the right way.
>> second, I copied a third party demo, it works well but still have some
>> warning for the OLD API and decode_audio.c did not use the latest API to
>> demostrate what ffmpeg suggest to do. I need a perfect demo, anybody could
>> help?
>>
> 1. 别在邮件的最上面回复内容,最好在最下面回复
> 2. 你是怎么跑的demo代码,全部过程能否详细描述一下
> 3. decode_audio.c里面是用的最新的API做音频解码的,不包含demux操作,仅仅是解码,而且是音频解码
> 4. 最好还是把你的全部过程和你的代码贴出来,大伙才好确认问题
>
> 除了1,  另外三点应该能得到你想要的答复,这个是api使用的列表,估计能得到你想要的答复的可能性不大,因为大伙不知道你怎么做的,不知道你代码实现,
> 如果能够按照我说的三点做一下,也许有结果。
>
>
>> Best regards,
>> pp
>>
>>
>>
>>
>> ------------------ 原始邮件 ------------------
>> *发件人:* "Gonzalo Garramuño";<ggarra13 at gmail.com>;
>> *发送时间:* 2017年5月12日(星期五) 晚上9:15
>> *收件人:* "This list is about using libavcodec, libavformat, libavutil,
>> libavdevice and libavfilter."<libav-user at ffmpeg.org>;
>> *主题:* Re: [Libav-user]回复: just wanna get a decode demo for libav
>>
>>
>>
>> El 12/05/17 a las 07:25, 坚定前行 escribió:
>>
>> Hi,
>>
>> that's the demo I tried
>> with warning 'avcodec_decode_audio4' is deprecated.
>> and that demo could not work with : Codec not found.
>>
>> Best regards,
>> pp
>>
>> Usually, if you get "codec not found" it means your ffmpeg compilation
>> was lacking a certain codec.  The audio example uses mpeg2 audio, so you
>> need to have ffmpeg compiled with mpeg2.
>> You can check the codecs you have by doing:
>>
>> $ ffmpeg -codecs
>>
>> For it to work, you should have a line like:
>>
>>  DEA.L. mp2                  MP2 (MPEG audio layer 2) (decoders: mp2
>> mp2float ) (encoders: mp2 mp2fixed )
>>
>>
>>
>> _______________________________________________
>> Libav-user mailing list
>> Libav-user at ffmpeg.org
>> http://ffmpeg.org/mailman/listinfo/libav-user
>>
>>
>

给你一段diff 参考一下:


diff --git a/doc/examples/demuxing_decoding.c
b/doc/examples/demuxing_decoding.c
index b1a216abb4..3c5190c28b 100644
--- a/doc/examples/demuxing_decoding.c
+++ b/doc/examples/demuxing_decoding.c
@@ -60,6 +60,84 @@ static int audio_frame_count = 0;
  * needs. Look for the use of refcount in this example to see what are the
  * differences of API usage between them. */
 static int refcount = 0;
+static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize,
+                     char *filename)
+{
+    FILE *f;
+    int i;
+
+    f = fopen(filename,"w");
+    fprintf(f, "P5\n%d %d\n%d\n", xsize, ysize, 255);
+    for (i = 0; i < ysize; i++)
+        fwrite(buf + i * wrap, 1, xsize, f);
+    fclose(f);
+}
+
+static void decode_video(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame
*frame,
+                   const char *filename)
+{
+    char buf[1024];
+    int ret;
+
+    ret = avcodec_send_packet(dec_ctx, pkt);
+    if (ret < 0) {
+        fprintf(stderr, "Error sending a packet for decoding\n");
+        exit(1);
+    }
+
+    while (ret >= 0) {
+        ret = avcodec_receive_frame(dec_ctx, frame);
+        if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
+            return;
+        else if (ret < 0) {
+            fprintf(stderr, "Error during decoding\n");
+            exit(1);
+        }
+
+        printf("saving frame %3d\n", dec_ctx->frame_number);
+        fflush(stdout);
+
+        /* the picture is allocated by the decoder. no need to
+           free it */
+        snprintf(buf, sizeof(buf), "%s-%d", filename,
dec_ctx->frame_number);
+        pgm_save(frame->data[0], frame->linesize[0],
+                 frame->width, frame->height, buf);
+    }
+}
+
+
+static void decode_audio(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame
*frame, FILE *outfile)
+{
+    int i, ch;
+    int ret, data_size;
+
+    /* send the packet with the compressed data to the decoder */
+    ret = avcodec_send_packet(dec_ctx, pkt);
+    if (ret < 0) {
+        fprintf(stderr, "Error submitting the packet to the decoder\n");
+        exit(1);
+    }
+
+    /* read all the output frames (in general there may be any number of
them */
+    while (ret >= 0) {
+        ret = avcodec_receive_frame(dec_ctx, frame);
+        if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
+            return;
+        else if (ret < 0) {
+            fprintf(stderr, "Error during decoding\n");
+            exit(1);
+        }
+        data_size = av_get_bytes_per_sample(dec_ctx->sample_fmt);
+        if (data_size < 0) {
+            /* This should not occur, checking just for paranoia */
+            fprintf(stderr, "Failed to calculate data size\n");
+            exit(1);
+        }
+        for (i = 0; i < frame->nb_samples; i++)
+            for (ch = 0; ch < dec_ctx->channels; ch++)
+                fwrite(frame->data[ch] + data_size*i, 1, data_size,
outfile);
+    }
+}

 static int decode_packet(int *got_frame, int cached)
 {
@@ -69,73 +147,9 @@ static int decode_packet(int *got_frame, int cached)
     *got_frame = 0;

     if (pkt.stream_index == video_stream_idx) {
-        /* decode video frame */
-        ret = avcodec_decode_video2(video_dec_ctx, frame, got_frame, &pkt);
-        if (ret < 0) {
-            fprintf(stderr, "Error decoding video frame (%s)\n",
av_err2str(ret));
-            return ret;
-        }
-
-        if (*got_frame) {
-
-            if (frame->width != width || frame->height != height ||
-                frame->format != pix_fmt) {
-                /* To handle this change, one could call av_image_alloc
again and
-                 * decode the following frames into another rawvideo file.
*/
-                fprintf(stderr, "Error: Width, height and pixel format
have to be "
-                        "constant in a rawvideo file, but the width,
height or "
-                        "pixel format of the input video changed:\n"
-                        "old: width = %d, height = %d, format = %s\n"
-                        "new: width = %d, height = %d, format = %s\n",
-                        width, height, av_get_pix_fmt_name(pix_fmt),
-                        frame->width, frame->height,
-                        av_get_pix_fmt_name(frame->format));
-                return -1;
-            }
-
-            printf("video_frame%s n:%d coded_n:%d\n",
-                   cached ? "(cached)" : "",
-                   video_frame_count++, frame->coded_picture_number);
-
-            /* copy decoded frame to destination buffer:
-             * this is required since rawvideo expects non aligned data */
-            av_image_copy(video_dst_data, video_dst_linesize,
-                          (const uint8_t **)(frame->data), frame->linesize,
-                          pix_fmt, width, height);
-
-            /* write to rawvideo file */
-            fwrite(video_dst_data[0], 1, video_dst_bufsize,
video_dst_file);
-        }
+        decode_video(video_dec_ctx, &pkt, frame, video_dst_filename);
     } else if (pkt.stream_index == audio_stream_idx) {
-        /* decode audio frame */
-        ret = avcodec_decode_audio4(audio_dec_ctx, frame, got_frame, &pkt);
-        if (ret < 0) {
-            fprintf(stderr, "Error decoding audio frame (%s)\n",
av_err2str(ret));
-            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);
-
-        if (*got_frame) {
-            size_t unpadded_linesize = frame->nb_samples *
av_get_bytes_per_sample(frame->format);
-            printf("audio_frame%s n:%d nb_samples:%d pts:%s\n",
-                   cached ? "(cached)" : "",
-                   audio_frame_count++, frame->nb_samples,
-                   av_ts2timestr(frame->pts, &audio_dec_ctx->time_base));
-
-            /* Write the raw audio data samples of the first plane. This
works
-             * fine for packed formats (e.g. AV_SAMPLE_FMT_S16). However,
-             * most audio decoders output planar audio, which uses a
separate
-             * plane of audio samples for each channel (e.g.
AV_SAMPLE_FMT_S16P).
-             * In other words, this code will write only the first audio
channel
-             * in these cases.
-             * You should use libswresample or libavfilter to convert the
frame
-             * to packed data. */
-            fwrite(frame->extended_data[0], 1, unpadded_linesize,
audio_dst_file);
-        }
+        decode_audio(audio_dec_ctx, &pkt, frame, audio_dst_file);
     }

     /* If we use frame reference counting, we own the data and need
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20170513/92918948/attachment.html>


More information about the Libav-user mailing list