[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