2

我正在使用下面粘贴的以下标准代码(参考:http ://dranger.com/ffmpeg/ )在使用 ndk 的 android 中使用 ffmpeg。我的代码使用 gcc 编译器在 ubuntu 10.04 中运行良好。但是我在android中遇到了一个问题。问题av_read_frame(pFormatCtx, &packet)总是在返回packet.stream_index=0。我已经使用各种 rtsp url 测试了我的代码,并且在所有情况下我都有相同的行为。我没有任何链接或编译问题,因为除了这个问题之外,一切似乎都运行良好。我试图从过去 2 天开始解决这个问题,但我被严重卡住了。请指出我正确的方向。

#include <jni.h>
#include <android/log.h>

#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>

#include <stdio.h>
#define DEBUG_TAG "mydebug_ndk"

jint Java_com_example_tut2_MainActivity_myfunc(JNIEnv * env, jobject this,jstring myjurl) {
  AVFormatContext *pFormatCtx = NULL;
  int             i, videoStream;
  AVCodecContext  *pCodecCtx = NULL;
  AVCodec         *pCodec = NULL;
  AVFrame         *pFrame = NULL;
  AVPacket        packet;
  int             frameFinished;

  AVDictionary    *optionsDict = NULL;
  struct SwsContext *sws_ctx = NULL;

  jboolean isCopy;
  const char * mycurl = (*env)->GetStringUTFChars(env, myjurl, &isCopy);
  __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK:p2: [%s]", mycurl);

  // Register all formats and codecs
  av_register_all();
  avformat_network_init();
  // Open video file
  __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK:before_open");

  if(avformat_open_input(&pFormatCtx, mycurl, NULL, NULL)!=0)
      return -1;
  __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "start: %d\t%d\n",pFormatCtx->raw_packet_buffer_remaining_size,pFormatCtx->max_index_size);

  (*env)->ReleaseStringUTFChars(env, myjurl, mycurl);
  __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK:before_stream");
  // Retrieve stream information
  if(avformat_find_stream_info(pFormatCtx, NULL)<0)
      return -1;
  __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK:after_stream");
  // Find the first video stream
  videoStream=-1;
  for(i=0; i<pFormatCtx->nb_streams; i++)
      if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) {
        videoStream=i;
        break;
      }
  if(videoStream==-1)
      return -1; // Didn't find a video stream
  __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK:after_videostream");
  // Get a pointer to the codec context for the video stream
  pCodecCtx=pFormatCtx->streams[videoStream]->codec;
  __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK:after_codec_context");

  // Find the decoder for the video stream
  pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
  __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK:after_decoder");

  if(pCodec==NULL)
      return -1;
  __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK:found_decoder");

  // Open codec
  if(avcodec_open2(pCodecCtx, pCodec, &optionsDict)<0)
      return -1;
  // Allocate video frame
  pFrame=avcodec_alloc_frame();
  sws_ctx = sws_getContext(pCodecCtx->width,pCodecCtx->height,pCodecCtx->pix_fmt,pCodecCtx->width,
        pCodecCtx->height,PIX_FMT_YUV420P,SWS_BILINEAR,NULL,NULL,NULL);
  __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK:before_while");

  int count=0;
  while(av_read_frame(pFormatCtx, &packet)>=0) {
        __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "entered while: %d   %d   %d\n", packet.duration,packet.stream_index,packet.size);

      if(packet.stream_index==videoStream) {
          // Decode video frame
          //break;
          avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished,&packet);
          __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK:in_while");
          if(frameFinished) {
              __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK:gng_out_of_while");
                break;
          }
      }

      // Free the packet that was allocated by av_read_frame
      av_free_packet(&packet);
      if(++count>1000)
         return -2; //infinite while loop
  }
  __android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK:after_while");

  // Free the YUV frame
  av_free(pFrame);
  // Close the codec
  avcodec_close(pCodecCtx);
  // Close the video file
  avformat_close_input(&pFormatCtx);

  return 0;

}
4

1 回答 1

0

我也有同样的问题。经过我的测试,我发现了我的错误,希望可以帮助你。

我的 av_read_frame() 也总是返回流索引 0 的 av_pkg;

问题是:我混合了两个版本的 ffmpeg 库。

之前,我安装的是 0.9.x 的 ffmpeg 现在,我安装的是 1.2 的 ffmpeg

这些库的版本不同。我使用了 0.9.x 的一些库和 1.2 的其他库。所以...发生错误。

我解决方案:

卸载所有版本的 ffmpeg ,然后重新安装一个版本的 ffmpeg(me->1.2)。av_read_frame() 正确。:)

于 2013-04-09T03:45:37.457 回答