From d233ba9214437dd5b97f3a48d93e37d7a623aec4 Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Thu, 16 Nov 2017 18:51:01 +0100 Subject: [PATCH 1/5] convert jpg to m2v with libavcodec, need --enable-demuxer=image2 Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/92646d5ad6a2b42f1b841fab68fa5f50553441d5 Author: Jacek Jendrzej Date: 2017-11-16 (Thu, 16 Nov 2017) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libarmbox/video.cpp | 131 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 127 insertions(+), 4 deletions(-) diff --git a/libarmbox/video.cpp b/libarmbox/video.cpp index 8cbc631..1d27454 100644 --- a/libarmbox/video.cpp +++ b/libarmbox/video.cpp @@ -40,6 +40,12 @@ #include +extern "C" +{ +#include +#include +} + #define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_VIDEO, this, args) #define lt_info(args...) _lt_info(TRIPLE_DEBUG_VIDEO, this, args) #define lt_debug_c(args...) _lt_debug(TRIPLE_DEBUG_VIDEO, NULL, args) @@ -141,6 +147,126 @@ static const char *vid_modes[] = { #define VIDEO_STREAMTYPE_H265_HEVC 7 #define VIDEO_STREAMTYPE_AVS 16 +void init_parameters(AVFrame* in_frame, AVCodecContext *codec_context) +{ + /* put sample parameters */ + codec_context->bit_rate = 400000; + /* resolution must be a multiple of two */ + codec_context->width = (in_frame->width/2)*2; + codec_context->height = (in_frame->height/2)*2; + /* frames per second */ + codec_context->time_base = (AVRational ) { 1, 60 }; + codec_context->gop_size = 10; /* emit one intra frame every ten frames */ + codec_context->max_b_frames = 1; + codec_context->pix_fmt = AV_PIX_FMT_YUV420P; +} + +void write_frame(AVFrame* in_frame, FILE* fp) +{ + if(in_frame == NULL || fp == NULL) + return; + AVCodec *codec = avcodec_find_encoder(AV_CODEC_ID_MPEG2VIDEO); + if (codec) + { + AVCodecContext *codec_context = avcodec_alloc_context3(codec); + if (codec_context) + { + init_parameters(in_frame, codec_context); + if (avcodec_open2(codec_context, codec, 0) != -1){ + AVPacket pkt; + av_init_packet(&pkt); + /* encode the image */ + int got_output = 0; + int ret = avcodec_encode_video2(codec_context, &pkt, in_frame, &got_output); + if (ret != -1){ + if (got_output){ + fwrite(pkt.data, 1, pkt.size, fp); + av_packet_unref(&pkt); + } + int i =1; + for (got_output = 1; got_output; i++){ + /* get the delayed frames */ + in_frame->pts = i; + ret = avcodec_encode_video2(codec_context, &pkt, 0, &got_output); + if (ret != -1 && got_output){ + fwrite(pkt.data, 1, pkt.size, fp); + av_packet_unref(&pkt); + } + } + avcodec_close(codec_context); + av_free(codec_context); + } + } + } + } +} + +int decode_frame(AVCodecContext *codecContext,AVPacket &packet, FILE* fp) +{ + int decode_ok = 0; + AVFrame *frame = av_frame_alloc(); + if(frame){ + if ((avcodec_decode_video2(codecContext, frame, &decode_ok, &packet)) < 0 || !decode_ok){ + av_frame_free(&frame); + return -1; + } + write_frame(frame, fp); + av_frame_free(&frame); + } + return 0; + +} + +AVCodecContext* open_codec(AVMediaType mediaType, AVFormatContext* formatContext) +{ + int stream_index = av_find_best_stream(formatContext, mediaType, -1, -1, NULL, 0); + if (stream_index < 0){ + return NULL; + } + AVCodecContext * codecContext = formatContext->streams[stream_index]->codec; + AVCodec *codec = avcodec_find_decoder(codecContext->codec_id); + if (!codec){ + return NULL; + } + if ((avcodec_open2(codecContext, codec, NULL)) != 0){ + return NULL; + } + + return codecContext; +} + +int image_to_mpeg2(const char *image_name, const char *encode_name) +{ + int ret = 0; + av_register_all(); + avcodec_register_all(); + + AVFormatContext *formatContext = avformat_alloc_context(); + if ((ret = avformat_open_input(&formatContext, image_name, NULL, NULL)) == 0){ + AVCodecContext *codecContext = open_codec(AVMEDIA_TYPE_VIDEO, formatContext); + if(codecContext){ + AVPacket packet; + av_init_packet(&packet); + if ((ret = av_read_frame(formatContext, &packet)) !=-1){ + FILE* fp = fopen(encode_name, "wb"); + if(fp){ + if(decode_frame(codecContext, packet, fp) != 1){ + /* add sequence end code to have a real mpeg file */ + uint8_t endcode[] = { 0, 0, 1, 0xb7 }; + fwrite(endcode, 1, sizeof(endcode), fp); + fclose(fp); + } + } + avcodec_close(codecContext); + av_free_packet(&packet); + } + avformat_close_input(&formatContext); + } + } + av_free(formatContext); + return 0; +} + cVideo::cVideo(int, void *, void *, unsigned int unit) { lt_debug("%s unit %u\n", __func__, unit); @@ -431,7 +557,6 @@ void cVideo::ShowPicture(const char * fname, const char *_destname) static const unsigned char pes_header[] = {0x0, 0x0, 0x1, 0xe0, 0x00, 0x00, 0x80, 0x80, 0x5, 0x21, 0x0, 0x1, 0x0, 0x1}; static const unsigned char seq_end[] = { 0x00, 0x00, 0x01, 0xB7 }; char destname[512]; - char cmd[512]; char *p; int mfd; struct stat st, st2; @@ -472,9 +597,7 @@ void cVideo::ShowPicture(const char * fname, const char *_destname) u.actime = time(NULL); u.modtime = st2.st_mtime; /* it does not exist or has a different date, so call ffmpeg... */ - sprintf(cmd, "ffmpeg -y -f mjpeg -i '%s' -s 1280x720 -aspect 16:9 '%s' >/dev/null", - fname, destname); - system(cmd); /* TODO: use libavcodec to directly convert it */ + image_to_mpeg2(fname, destname); utime(destname, &u); } } From cb10177b2f38a18382a92eab965b0afef724960a Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Thu, 16 Nov 2017 18:58:13 +0100 Subject: [PATCH 2/5] fix close fp Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/d55f59258637585146e4343b8d8f0a7d3cd04b12 Author: Jacek Jendrzej Date: 2017-11-16 (Thu, 16 Nov 2017) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libarmbox/video.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libarmbox/video.cpp b/libarmbox/video.cpp index 1d27454..3eaac62 100644 --- a/libarmbox/video.cpp +++ b/libarmbox/video.cpp @@ -254,8 +254,8 @@ int image_to_mpeg2(const char *image_name, const char *encode_name) /* add sequence end code to have a real mpeg file */ uint8_t endcode[] = { 0, 0, 1, 0xb7 }; fwrite(endcode, 1, sizeof(endcode), fp); - fclose(fp); } + fclose(fp); } avcodec_close(codecContext); av_free_packet(&packet); From d891ac338115e8615a635c179ac7bd245b127876 Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Thu, 16 Nov 2017 19:09:16 +0100 Subject: [PATCH 3/5] check alloc AVFormatContext Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/fd512df7cbd3f2d72ee63bd9b327ff04a24bde8d Author: Jacek Jendrzej Date: 2017-11-16 (Thu, 16 Nov 2017) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libarmbox/video.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/libarmbox/video.cpp b/libarmbox/video.cpp index 3eaac62..19b41b3 100644 --- a/libarmbox/video.cpp +++ b/libarmbox/video.cpp @@ -225,14 +225,10 @@ AVCodecContext* open_codec(AVMediaType mediaType, AVFormatContext* formatContext } AVCodecContext * codecContext = formatContext->streams[stream_index]->codec; AVCodec *codec = avcodec_find_decoder(codecContext->codec_id); - if (!codec){ + if (codec && (avcodec_open2(codecContext, codec, NULL)) != 0){ return NULL; } - if ((avcodec_open2(codecContext, codec, NULL)) != 0){ - return NULL; - } - - return codecContext; + return codecContext; } int image_to_mpeg2(const char *image_name, const char *encode_name) @@ -242,7 +238,7 @@ int image_to_mpeg2(const char *image_name, const char *encode_name) avcodec_register_all(); AVFormatContext *formatContext = avformat_alloc_context(); - if ((ret = avformat_open_input(&formatContext, image_name, NULL, NULL)) == 0){ + if (formatContext && (ret = avformat_open_input(&formatContext, path, NULL, NULL)) == 0){ AVCodecContext *codecContext = open_codec(AVMEDIA_TYPE_VIDEO, formatContext); if(codecContext){ AVPacket packet; From 54b4c2a8770d74409e2c660daed4428fe236cab4 Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Thu, 16 Nov 2017 19:10:40 +0100 Subject: [PATCH 4/5] fix last commit Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/cefff907e542b71ac5340d480f19a032559c1823 Author: Jacek Jendrzej Date: 2017-11-16 (Thu, 16 Nov 2017) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libarmbox/video.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libarmbox/video.cpp b/libarmbox/video.cpp index 19b41b3..1192f08 100644 --- a/libarmbox/video.cpp +++ b/libarmbox/video.cpp @@ -238,7 +238,7 @@ int image_to_mpeg2(const char *image_name, const char *encode_name) avcodec_register_all(); AVFormatContext *formatContext = avformat_alloc_context(); - if (formatContext && (ret = avformat_open_input(&formatContext, path, NULL, NULL)) == 0){ + if (formatContext && (ret = avformat_open_input(&formatContext, image_name, NULL, NULL)) == 0){ AVCodecContext *codecContext = open_codec(AVMEDIA_TYPE_VIDEO, formatContext); if(codecContext){ AVPacket packet; From a23d33b8d0f61290e4a7c7b9e17abe23378b8722 Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Fri, 17 Nov 2017 06:34:13 +0100 Subject: [PATCH 5/5] fix logic and possible memleak Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/6b9e79094ac7365f4713371a5788d4ae704a35ee Author: Jacek Jendrzej Date: 2017-11-17 (Fri, 17 Nov 2017) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libarmbox/video.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/libarmbox/video.cpp b/libarmbox/video.cpp index 1192f08..41e283d 100644 --- a/libarmbox/video.cpp +++ b/libarmbox/video.cpp @@ -220,15 +220,19 @@ int decode_frame(AVCodecContext *codecContext,AVPacket &packet, FILE* fp) AVCodecContext* open_codec(AVMediaType mediaType, AVFormatContext* formatContext) { int stream_index = av_find_best_stream(formatContext, mediaType, -1, -1, NULL, 0); - if (stream_index < 0){ - return NULL; + if (stream_index >=0 ){ + AVCodecContext * codecContext = formatContext->streams[stream_index]->codec; + if(codecContext){ + AVCodec *codec = avcodec_find_decoder(codecContext->codec_id); + if(codec){ + if ((avcodec_open2(codecContext, codec, NULL)) != 0){ + return NULL; + } + } + return codecContext; + } } - AVCodecContext * codecContext = formatContext->streams[stream_index]->codec; - AVCodec *codec = avcodec_find_decoder(codecContext->codec_id); - if (codec && (avcodec_open2(codecContext, codec, NULL)) != 0){ - return NULL; - } - return codecContext; + return NULL; } int image_to_mpeg2(const char *image_name, const char *encode_name) @@ -253,11 +257,11 @@ int image_to_mpeg2(const char *image_name, const char *encode_name) } fclose(fp); } - avcodec_close(codecContext); av_free_packet(&packet); } - avformat_close_input(&formatContext); + avcodec_close(codecContext); } + avformat_close_input(&formatContext); } av_free(formatContext); return 0;