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) / / bit conversion path may return 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
/ / traverse the file stream, find the first video stream and record stream encoding information
videoStream = -1;
for (i = 0; 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
/ / get the encoded video stream context pointer
pCodecCtx = pFormatCtx-> streams [videoStream] -> codec;
/ / construct the scale context, conversing to PIX_FMT_RGB24
/ / Set the rendering format based on the encoded information
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
/ / Find in a library which supports this format decoder
pCodec = avcodec_find_decoder (pCodecCtx-> codec_id);
if (pCodec == NULL)
{
fprintf (stderr, "Unsupported codec! \ n");
return -1; / / Codec not found
}
/ / Open codec
/ / open the decoder
if (avcodec_open2 (pCodecCtx, pCodec, NULL) <0)
return -1; / / Could not open codec
/ / Allocate video frame
/ / assign a frame pointer to the original frame after decoding
pFrame = avcodec_alloc_frame ();
/ / Allocate an AVFrame structure
/ / assign a frame pointer stored into the frame after 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
/ / append to pFrameRGB frame memory allocated
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) / / read a frame
{
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
/ / decode the 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);
/ / put the frame into rgb
/ / If only the key frame extraction, add this
/ / 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
/ / save the previous five
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
/ / release the reading frame memory
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;
}
This is my copy of the code from the Internet, and then changed some ways, because I was using the 2.0 so some methods have changed, now there is a problem is packet.stream_index == videoStream their values do not match, packet.stream_index has been a seven-digit, I do not know why this is. . What is the reason endian?
------ Solution ---------------------------------------- ----
suggested parameters are printed out to see which step is wrong, pFormatCtx-> nb_streams can look at a few
------ Solution ----------- ---------------------------------
you use VS breakpoint walked guess when you do can come out it
------ reference ------------------------------------ ---
amount. . How VS breakpoint amount. . Before that is the byte order problem. . Add to colleagues that the next test can. . Discovery is the header file too old. .
没有评论:
发表评论