android中ffmpeg中的Av_read_frame函数总是返回数据包.Stream_index为0



我使用下面粘贴的标准代码(参考:http://dranger.com/ffmpeg/)在android中使用ndk使用ffmpeg。我的代码在ubuntu 10.04使用gcc编译器工作良好。但是我在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: %dt%dn",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   %dn", 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;
}

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

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

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

在前面,我安装了0.9.x的ffmpeg现在,我安装ffmpeg的1.2

库是不同的版本。我使用了一些来自0.9的lib。X和其他从1.2。所以…错误发生。

我的解决方案:

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

最新更新