#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
int file;
int saveAsJPEG(AVFrame *pFrame, int index) {
fprintf(stdout, "ok 0 \n");
int width = pFrame->width;
int height = pFrame->height;
AVCodecContext *pCodeCtx = NULL;
char out_name[32];
sprintf(out_name, "frame%d.png", index);
fprintf(stdout, "out_name: %d \n", index);
AVFormatContext *output_format_context = NULL;
avformat_alloc_output_context2(&output_format_context, NULL, NULL,
out_name);
fprintf(stdout, "mime_type %s \n",
output_format_context->oformat->mime_type);
AVStream *pAVStream = avformat_new_stream(output_format_context, 0);
if (pAVStream == NULL) {
return -1;
}
AVCodecParameters *parameters = pAVStream->codecpar;
parameters->codec_id = output_format_context->oformat->video_codec;
parameters->codec_type = AVMEDIA_TYPE_VIDEO;
parameters->format = AV_PIX_FMT_YUVJ420P;
parameters->width = pFrame->width;
parameters->height = pFrame->height;
AVCodec *pCodec = avcodec_find_encoder(pAVStream->codecpar->codec_id);
pCodeCtx = avcodec_alloc_context3(NULL);
avcodec_parameters_to_context(pCodeCtx, pAVStream->codecpar);
pCodeCtx->time_base = (AVRational ) { 1, 25 };
avcodec_open2(pCodeCtx, pCodec, NULL);
avformat_write_header(output_format_context, NULL);
int y_size = width * height;
AVPacket pkt;
av_new_packet(&pkt, y_size * 10);
printf("av_new_packet %d \n", index);
int ret = avcodec_send_frame(pCodeCtx, pFrame);
if (ret < 0) {
perror("avcodec_send_frame");
return -1;
}
ret = avcodec_receive_packet(pCodeCtx, &pkt);
if (ret < 0) {
perror("avcodec_receive_packet");
return -1;
}
printf("start write packet to file\n");
printf("pkt.size = %d\n", pkt.size);
if (write(file, pkt.data, pkt.size) < 0)
perror("write");
else
printf("write success \n");
ret = av_write_frame(output_format_context, &pkt);
if (ret < 0) {
printf("Could not av_write_frame");
return -1;
}
av_packet_unref(&pkt);
av_write_trailer(output_format_context);
avcodec_close(pCodeCtx);
avio_close(output_format_context->pb);
avformat_free_context(output_format_context);
return 0;
}
int main(int argc, char **argv) {
int ret;
file = open("output.yuv", O_WRONLY | O_CREAT | O_TRUNC);
const char *inFileName = "../missu.mp4";
AVFormatContext *ifmt_ctx = NULL;
AVPacket *packet = NULL;
packet = av_packet_alloc();
AVFrame *pFrame = NULL;
AVCodecContext *decode_ctx;
pFrame = av_frame_alloc();
if (avformat_open_input(&ifmt_ctx, inFileName, NULL, NULL) != 0) {
perror("avformat_open_input");
return -1;
}
if (avformat_find_stream_info(ifmt_ctx, NULL) < 0) {
perror("avformat_find_stream_info");
fprintf(stdout, "Couldn't find stream information \n");
return -1;
}
printf("streams number : %d \n", ifmt_ctx->nb_streams);
if (ifmt_ctx->nb_streams == 0) {
printf("nb_streams is 0,exit \n");
return -1;
}
int videoStream = av_find_best_stream(ifmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1,
NULL, 0);
if (videoStream == -1) {
printf("Didn't find a video stream \n");
return -1;
}
AVStream *stream = ifmt_ctx->streams[videoStream];
const AVCodec *decoder = avcodec_find_decoder(stream->codecpar->codec_id);
printf("decoder->name = %s \n", decoder->name);
printf("decoder->long_name = %s \n", decoder->long_name);
printf("decoder->type = %s \n", decoder->type);
printf("decoder->AVCodecID = %d \n", decoder->id);
decode_ctx = avcodec_alloc_context3(decoder);
if (!decode_ctx) {
fprintf(stderr, "Could not allocate video codec context\n");
exit(1);
}
ret = avcodec_parameters_to_context(decode_ctx, stream->codecpar);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR,
"Failed to copy decoder parameters to input decoder context "
"for stream\n");
return ret;
}
ret = avcodec_open2(decode_ctx, decoder, NULL);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Failed to open decoder for stream \n");
return ret;
}
int i = 0;
while (av_read_frame(ifmt_ctx, packet) >= 0) {
if (packet->stream_index == videoStream) {
i++;
dd: ret = avcodec_send_packet(decode_ctx, packet);
if (ret < 0) {
if (ret == AVERROR(EAGAIN)) {
av_log(NULL, AV_LOG_ERROR, "AVERROR(EAGAIN) \n");
}
av_log(NULL, AV_LOG_ERROR, "Decoding failed: %d \n", ret);
break;
}
ret = avcodec_receive_frame(decode_ctx, pFrame);
if (ret == AVERROR(EAGAIN)) {
goto dd;
}
if (ret != 0) {
av_log(NULL, AV_LOG_ERROR,
"avcodec_receive_frame: failed %d \n", ret);
break;
}
if (ret == 0) {
fprintf(stdout, "we get a video frame \n");
saveAsJPEG(pFrame, i);
}
}
}
end: av_frame_free(&pFrame);
av_packet_free(&packet);
avformat_close_input(&ifmt_ctx);
return 0;
}