请选择 进入手机版 | 继续访问电脑版

ChinaFFmpeg

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 5775|回复: 1

[源码] bitstream如何获取?

[复制链接]
发表于 2013-11-7 22:13:32 | 显示全部楼层 |阅读模式
Hi ALL


问题1
我想获取文件解析后的原始bit数据,有什么办法可以获取呢?
参考的代码是doc里面的demo代码。
http://www.ffmpeg.org/doxygen/2.0/doc_2examples_2demuxing_8c-example.html
我尝试过把AVPacket的 data 写到文件中去,我记得2.0版本mp4是有效的,我发现2.1版本不可以了,难道发生了变化?


Thanks




回复

使用道具 举报

发表于 2013-11-14 08:51:52 | 显示全部楼层

  1. diff --git a/doc/examples/demuxing.c b/doc/examples/demuxing.c
  2. index 8a1b69b..e459cf0 100644
  3. --- a/doc/examples/demuxing.c
  4. +++ b/doc/examples/demuxing.c
  5. @@ -47,10 +47,6 @@ static uint8_t *video_dst_data[4] = {NULL};
  6. static int      video_dst_linesize[4];
  7. static int video_dst_bufsize;

  8. -static uint8_t **audio_dst_data = NULL;
  9. -static int       audio_dst_linesize;
  10. -static int audio_dst_bufsize;
  11. -
  12. static int video_stream_idx = -1, audio_stream_idx = -1;
  13. static AVFrame *frame = NULL;
  14. static AVPacket pkt;
  15. @@ -60,6 +56,7 @@ static int audio_frame_count = 0;
  16. static int decode_packet(int *got_frame, int cached)
  17. {
  18.      int ret = 0;
  19. +    int decoded = pkt.size;

  20.      if (pkt.stream_index == video_stream_idx) {
  21.          /* decode video frame */
  22. @@ -91,37 +88,32 @@ static int decode_packet(int *got_frame, int cached)
  23.              fprintf(stderr, "Error decoding audio frame\n");
  24.              return ret;
  25.          }
  26. +        /* Some audio decoders decode only part of the packet, and have to be
  27. +         * called again with the remainder of the packet data.
  28. +         * Sample: fate-suite/lossless-audio/luckynight-partial.shn
  29. +         * Also, some decoders might over-read the packet. */
  30. +        decoded = FFMIN(ret, pkt.size);

  31.          if (*got_frame) {
  32. +            size_t unpadded_linesize = frame->nb_samples * av_get_bytes_per_sample(frame->format);
  33.              printf("audio_frame%s n:%d nb_samples:%d pts:%s\n",
  34.                     cached ? "(cached)" : "",
  35.                     audio_frame_count++, frame->nb_samples,
  36.                     av_ts2timestr(frame->pts, &audio_dec_ctx->time_base));

  37. -            ret = av_samples_alloc(audio_dst_data, &audio_dst_linesize, av_frame_get_channels(frame),
  38. -                                   frame->nb_samples, frame->format, 1);
  39. -            if (ret < 0) {
  40. -                fprintf(stderr, "Could not allocate audio buffer\n");
  41. -                return AVERROR(ENOMEM);
  42. -            }
  43. -
  44. -            /* TODO: extend return code of the av_samples_* functions so that this call is not needed */
  45. -            audio_dst_bufsize =
  46. -                av_samples_get_buffer_size(NULL, av_frame_get_channels(frame),
  47. -                                           frame->nb_samples, frame->format, 1);
  48. -
  49. -            /* copy audio data to destination buffer:
  50. -             * this is required since rawaudio expects non aligned data */
  51. -            av_samples_copy(audio_dst_data, frame->data, 0, 0,
  52. -                            frame->nb_samples, av_frame_get_channels(frame), frame->format);
  53. -
  54. -            /* write to rawaudio file */
  55. -            fwrite(audio_dst_data[0], 1, audio_dst_bufsize, audio_dst_file);
  56. -            av_freep(&audio_dst_data[0]);
  57. +            /* Write the raw audio data samples of the first plane. This works
  58. +             * fine for packed formats (e.g. AV_SAMPLE_FMT_S16). However,
  59. +             * most audio decoders output planar audio, which uses a separate
  60. +             * plane of audio samples for each channel (e.g. AV_SAMPLE_FMT_S16P).
  61. +             * In other words, this code will write only the first audio channel
  62. +             * in these cases.
  63. +             * You should use libswresample or libavfilter to convert the frame
  64. +             * to packed data. */
  65. +            fwrite(frame->extended_data[0], 1, unpadded_linesize, audio_dst_file);
  66.          }
  67.      }

  68. -    return ret;
  69. +    return decoded;
  70. }

  71. static int open_codec_context(int *stream_idx,
  72. @@ -244,8 +236,6 @@ int main (int argc, char **argv)
  73.      }

  74.      if (open_codec_context(&audio_stream_idx, fmt_ctx, AVMEDIA_TYPE_AUDIO) >= 0) {
  75. -        int nb_planes;
  76. -
  77.          audio_stream = fmt_ctx->streams[audio_stream_idx];
  78.          audio_dec_ctx = audio_stream->codec;
  79.          audio_dst_file = fopen(audio_dst_filename, "wb");
  80. @@ -254,15 +244,6 @@ int main (int argc, char **argv)
  81.              ret = 1;
  82.              goto end;
  83.          }
  84. -
  85. -        nb_planes = av_sample_fmt_is_planar(audio_dec_ctx->sample_fmt) ?
  86. -            audio_dec_ctx->channels : 1;
  87. -        audio_dst_data = av_mallocz(sizeof(uint8_t *) * nb_planes);
  88. -        if (!audio_dst_data) {
  89. -            fprintf(stderr, "Could not allocate audio data buffers\n");
  90. -            ret = AVERROR(ENOMEM);
  91. -            goto end;
  92. -        }
  93.      }

  94.      /* dump input information to stderr */
  95. @@ -293,8 +274,15 @@ int main (int argc, char **argv)

  96.      /* read frames from the file */
  97.      while (av_read_frame(fmt_ctx, &pkt) >= 0) {
  98. -        decode_packet(&got_frame, 0);
  99. -        av_free_packet(&pkt);
  100. +        AVPacket orig_pkt = pkt;
  101. +        do {
  102. +            ret = decode_packet(&got_frame, 0);
  103. +            if (ret < 0)
  104. +                break;
  105. +            pkt.data += ret;
  106. +            pkt.size -= ret;
  107. +        } while (pkt.size > 0);
  108. +        av_free_packet(&orig_pkt);
  109.      }

  110.      /* flush cached frames */
  111. @@ -314,13 +302,25 @@ int main (int argc, char **argv)
  112.      }

  113.      if (audio_stream) {
  114. +        enum AVSampleFormat sfmt = audio_dec_ctx->sample_fmt;
  115. +        int n_channels = audio_dec_ctx->channels;
  116.          const char *fmt;

  117. -        if ((ret = get_format_from_sample_fmt(&fmt, audio_dec_ctx->sample_fmt)) < 0)
  118. +        if (av_sample_fmt_is_planar(sfmt)) {
  119. +            const char *packed = av_get_sample_fmt_name(sfmt);
  120. +            printf("Warning: the sample format the decoder produced is planar "
  121. +                   "(%s). This example will output the first channel only.\n",
  122. +                   packed ? packed : "?");
  123. +            sfmt = av_get_packed_sample_fmt(sfmt);
  124. +            n_channels = 1;
  125. +        }
  126. +
  127. +        if ((ret = get_format_from_sample_fmt(&fmt, sfmt)) < 0)
  128.              goto end;
  129. +
  130.          printf("Play the output audio file with the command:\n"
  131.                 "ffplay -f %s -ac %d -ar %d %s\n",
  132. -               fmt, audio_dec_ctx->channels, audio_dec_ctx->sample_rate,
  133. +               fmt, n_channels, audio_dec_ctx->sample_rate,
  134.                 audio_dst_filename);
  135.      }

  136. @@ -336,7 +336,6 @@ end:
  137.          fclose(audio_dst_file);
  138.      av_free(frame);
  139.      av_free(video_dst_data[0]);
  140. -    av_free(audio_dst_data);

  141.      return ret < 0;
  142. }
复制代码
上面是2.0到2.1的改动
在我这里测试是没有问题的
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|Archiver|ChinaFFmpeg

GMT+8, 2024-3-29 20:05 , Processed in 0.082577 second(s), 14 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表