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

坚定前行 powerpan at qq.com
Fri May 19 04:13:30 EEST 2017


------------------ 原始邮件 ------------------
发件人: "坚定前行";<powerpan at qq.com>;
发送时间: 2017年5月13日(星期六) 下午5:30
收件人: "libav-user"<libav-user at ffmpeg.org>; 

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









------------------ 原始邮件 ------------------
发件人: "lingjiujianke";<lingjiujianke at gmail.com>;
发送时间: 2017年5月13日(星期六) 上午6:44
收件人: "This list is about using libavcodec, libavformat, libavutil,libavdevice and libavfilter."<libav-user at ffmpeg.org>; 
抄送: "ggarra13"<ggarra13 at gmail.com>; 
主题: Re: [Libav-user]回复: 回复: just wanna get a decode demo for libav





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


code tested and found that's not fully implemented. cause FFMPEG could decode all the codecs but our new code couldn't, "codec not found" is the biggest problem. had to use old function like what FFMPEG.c did.


seem that still there is a long way to go to fully migrate old API to new one. will keep my eye open on that. or I could provide a music sample dir by cloud.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20170519/0d380d9c/attachment.html>


More information about the Libav-user mailing list