/*******************************************************************************************/
int test1(JNIEnv* env,jstring str)
{
AVFormatContext *pFormatCtx;
int             i, videoStream;
AVCodecContext  *pCodecCtx;
AVCodec         *pCodec;
AVFrame         *pFrame;
AVFrame         *pFrameRGB;
AVPacket        packet;
int             frameFinished;
int             numBytes;
uint8_t         *buffer;
struct SwsContext *img_convert_ctx;
int stream_index;
jbyte* stream_index_byte;
jbyte* videostream;
av_register_all();
avformat_network_init();
int open_url_error_flag;
int stream_info;
int open_codec_error ;
const jbyte* url ;
if(str == NULL)
return -1;
url = (*env)->GetStringUTFChars(env,str,NULL);
if(url == NULL)//转换路径有可能返回位null
return -1;
LOGE("test url %s",url);
open_url_error_flag = avformat_open_input(&pFormatCtx,url,NULL,NULL);
if(open_url_error_flag < 0)
return -1;
LOGE("open url error flag = %d",open_url_error_flag);
stream_info = avformat_find_stream_info(pFormatCtx,NULL);
LOGE("find stream info = %d",stream_info);
if(stream_info<0)
return -1;
av_dump_format(pFormatCtx,0,url,0); // 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 // Get a pointer to the codec context for the video stream
// 得到视频流编码的上下文指针
pCodecCtx=pFormatCtx->streams[videoStream]->codec; // construct the scale context, conversing to PIX_FMT_RGB24
// 根据编码信息设置渲染格式
img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt,
pCodecCtx->width, pCodecCtx->height, PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);
if(img_convert_ctx == NULL)
{
fprintf(stderr, "Cannot initialize the conversion context!\n");
//  exit(1);
return -1;
} // Find the decoder for the video stream
// 在库里面查找支持该格式的解码器
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL)
{
fprintf(stderr, "Unsupported codec!\n");
return -1; // Codec not found
}
// Open codec
// 打开解码器
if(avcodec_open2(pCodecCtx, pCodec,NULL)<0)
return -1; // Could not open codec // Allocate video frame
// 分配一个帧指针,指向解码后的原始帧
pFrame=avcodec_alloc_frame(); // Allocate an AVFrame structure
// 分配一个帧指针,指向存放转换成rgb后的帧
pFrameRGB=avcodec_alloc_frame();
if(pFrameRGB==NULL)
return -1; // Determine required buffer size and allocate buffer
numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t)); // buffer = new uint8_t[numBytes]; // Assign appropriate parts of buffer to image planes in pFrameRGB
// Note that pFrameRGB is an AVFrame, but AVFrame is a superset
// of AVPicture
// 给pFrameRGB帧附加上分配的内存
avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height); // Read frames and save first five frames to disk
i=0;
while(av_read_frame(pFormatCtx, &packet)>=0) // 读取一个帧
{
LOGE("packet.stream_index = %d",packet.stream_index);
LOGE("videoStream = %d",videoStream);
// stream_index_byte = intToByte(packet.stream_index);
// Is this a packet from the video stream?
if(packet.stream_index==videoStream)
{
// Decode video frame
// 解码该帧
avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
// Did we get a video frame?
if(frameFinished)
{
// Convert the image from its native format to RGB
// img_convert((AVPicture *)pFrameRGB, PIX_FMT_RGB24,
//  (AVPicture*)pFrame, pCodecCtx->pix_fmt, pCodecCtx->width,
//              pCodecCtx->height); // 把该帧转换成rgb // 如果只提取关键帧,加上这句
// if (pFrame->key_frame == 1)
sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
// Save the frame to disk
// 保存前5帧
if(++i<=5)
{
//  char pic[200];
//  sprintf(pic,"pic%d.bmp",i);
//  av_create_bmp(pic, pFrameRGB->data[0], pCodecCtx->width, pCodecCtx->height, 24);
SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height, i);
}
}
} // Free the packet that was allocated by av_read_frame
// 释放读取的帧内存
av_free_packet(&packet);
} // Free the RGB image
av_free(buffer);
av_free(pFrameRGB); // Free the YUV frame
av_free(pFrame); // Close the codec
avcodec_close(pCodecCtx); // Close the video file
av_close_input_file(pFormatCtx); return 0;
}这是我从网上拷贝的代码,然后改了一些方法,因为我用的是2.0的所以有些方法改变了,现在有一个问题就是 packet.stream_index==videoStream他们的值不一致,packet.stream_index 一直是一个7位数,我不清楚这是为啥。。是字节序的原因么?字节序 FFmpeg packet videoStream