message("* qt/avio")
-SET(THIS_LIB_VERSION 2.11.0)
+SET(THIS_LIB_VERSION 2.11.1)
set(s_qt_avio_headers
movie_saver.h
movie_loader.h
)
target_link_libraries(CSPavio PUBLIC
- ${LIBAV_LIBRARIES}
+ PRIVATE ${LIBAV_LIBRARIES}
${CMAKE_CURRENT_SOURCE_DIR}/../../../build-cmake/bin-win32/libCSPosd.dll.a
# ${CMAKE_CURRENT_SOURCE_DIR}/../../../build-cmake/bin-win32/libCSPgui.dll.a
${CMAKE_CURRENT_SOURCE_DIR}/../../../build-cmake/bin-win32/libCSPemu_utils.dll.a
#if defined(USE_LIBAV)
int MOVIE_LOADER::decode_audio(AVCodecContext *dec_ctx, int *got_frame)
{
- int ch;
int ret = 0;
#if (LIBAVCODEC_VERSION_MAJOR > 56)
/* send the packet with the compressed data to the decoder */
int MOVIE_LOADER::decode_video(AVCodecContext *dec_ctx, int *got_frame)
{
- int i, ch;
int ret = 0;
- int data_size;
#if (LIBAVCODEC_VERSION_MAJOR > 56)
/* send the packet with the compressed data to the decoder */
if(got_frame != NULL) *got_frame = 0;
//video_mutex->unlock();
}
- char str_buf2[AV_TS_MAX_STRING_SIZE] = {0};
+// char str_buf2[AV_TS_MAX_STRING_SIZE] = {0};
video_frame_count++;
if (*got_frame) {
//size_t unpadded_linesize = frame->nb_samples * av_get_bytes_per_sample((enum AVSampleFormat)frame->format);
- char str_buf[AV_TS_MAX_STRING_SIZE] = {0};
+// char str_buf[AV_TS_MAX_STRING_SIZE] = {0};
// AVCodecContext *c = avcodec_alloc_context3(NULL);
AVCodecContext *c = audio_dec_ctx;
if (c == NULL) {
bool MOVIE_LOADER::open(QString filename)
{
- int ret = 0, got_frame;
+ int ret = 0;
_filename = filename;
if(_filename.isEmpty()) return false;
audio_total_samples = 0;
/* register all formats and codecs */
+#if (LIBAVCODEC_VERSION_MAJOR <= 56)
av_register_all();
-
+#endif
/* open input file, and allocate format context */
if (avformat_open_input(&fmt_ctx, _filename.toLocal8Bit().constData(), NULL, NULL) < 0) {
p_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_MOVIE_LOADER, "Could not open source file %s\n", _filename.toLocal8Bit().constData());
src_height = video_dec_ctx->height;
pix_fmt = video_dec_ctx->pix_fmt;
AVRational rate;
+#if (LIBAVCODEC_VERSION_MAJOR > 56)
+ rate = video_stream->avg_frame_rate;
+#else
rate = av_stream_get_r_frame_rate(video_stream);
+#endif
frame_rate = av_q2d(rate);
if (ret < 0) {
p_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_MOVIE_LOADER, "Could not allocate raw video buffer\n");
int tmp_wait = fps_wait;
bool need_audio_transcode = false;
bool need_video_transcode = false;
- int i;
- int64_t total_packets_written = 0;
bool a_f, v_f;
a_f = v_f = false;
volatile bool old_recording = false;
need_video_transcode = true;
}
_write_frame:
+ int result_ts = 0;
+#if 0//(LIBAVCODEC_VERSION_MAJOR > 56)
+ if(audio_st.context != NULL) {
+ if(video_st.context != NULL) {
+ result_ts = av_compare_ts(video_st.next_pts, video_st.context->time_base,
+ audio_st.next_pts, audio_st.context->time_base);
+ } else {
+ result_ts = 1; // AUDIO ONLY
+ }
+ } else {
+ if(video_st.context != NULL) {
+ result_ts = -1; // VIDEO ONLY
+ }
+ }
+#else
+ result_ts = av_compare_ts(video_st.next_pts, video_st.st->codec->time_base,
+ audio_st.next_pts, audio_st.st->codec->time_base);
+#endif
if ((n_encode_video == 0) &&
- ((n_encode_audio != 0) || av_compare_ts(video_st.next_pts, video_st.st->codec->time_base,
- audio_st.next_pts, audio_st.st->codec->time_base) <= 0)) {
+ ((n_encode_audio != 0) ||
+ (result_ts <= 0))) {
n_encode_video = write_video_frame();
+ ret = n_encode_video;
if(n_encode_video < 0) {
p_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_MOVIE_SAVER, "MOVIE/Saver: Something wrong with encoding video.");
goto _final;
}
} else {
n_encode_audio = write_audio_frame();
+ ret = n_encode_audio;
if(n_encode_audio < 0) {
p_logger->debug_log(CSP_LOG_DEBUG, CSP_LOG_TYPE_MOVIE_SAVER, "MOVIE/Saver: Something wrong with encoding audio.");
goto _final;
struct SwsContext *sws_ctx;
struct SwrContext *swr_ctx;
+#if (LIBAVCODEC_VERSION_MAJOR > 56)
+ AVCodecContext *context;
+#endif
} OutputStream;
class OSD;
AVFormatContext *output_context;
AVCodec *audio_codec, *video_codec;
AVDictionary *raw_options_list;
-
+#endif
OutputStream video_st;
OutputStream audio_st;
-#endif
QString _filename;
bool bRunThread;
bool debug_timestamp;
AVDictionary *opt_arg = raw_options_list;
OutputStream *ost = &audio_st;
AVCodec *codec = audio_codec;
- AVCodecContext *c;
+ AVCodecContext *c = NULL;
int nb_samples;
int ret;
AVDictionary *opt = NULL;
+#if 0//(LIBAVCODEC_VERSION_MAJOR > 56)
+ c = ost->context;
+#else
c = ost->st->codec;
-
+#endif
/* open it */
av_dict_copy(&opt, opt_arg, 0);
ret = avcodec_open2(c, codec, &opt);
av_dict_free(&opt);
if (ret < 0) {
+#if 0//(LIBAVCODEC_VERSION_MAJOR > 56)
+ avcodec_free_context(&(ost->context));
+#endif
p_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_MOVIE_SAVER, "Could not open audio codec: %s\n", err2str(ret).toLocal8Bit().constData());
return false;
}
nb_samples = 10000;
else
nb_samples = c->frame_size;
-
ost->frame = (AVFrame *)alloc_audio_frame((uint64_t)c->sample_fmt, c->channel_layout,
c->sample_rate, nb_samples);
ost->tmp_frame = (AVFrame *)alloc_audio_frame((uint64_t)AV_SAMPLE_FMT_S16, c->channel_layout,
c->sample_rate, nb_samples);
/* create resampler context */
-#if 1
/* set options */
ost->swr_ctx = swr_alloc();
if (!ost->swr_ctx) {
+#if 0//(LIBAVCODEC_VERSION_MAJOR > 56)
+ avcodec_free_context(&(ost->context));
+#endif
p_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_MOVIE_SAVER, "Could not allocate resampler context\n");
return false;
}
av_opt_set_int (ost->swr_ctx, "out_sample_rate", c->sample_rate, 0);
av_opt_set_sample_fmt(ost->swr_ctx, "out_sample_fmt", c->sample_fmt, 0);
-#else
- ost->swr_ctx = swr_alloc_set_opts(NULL,
- AV_CH_LAYOUT_STEREO, c->sample_fmt, c->sample_rate,
- AV_CH_LAYOUT_STEREO, AV_SAMPLE_FMT_S16, audio_sample_rate,
- 0, NULL);
- if (ost->swr_ctx == NULL) {
- p_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_MOVIE_SAVER, "Failed to initialize the resampling context\n");
- return false;
- }
-#endif
/* initialize the resampling context */
if ((ret = swr_init(ost->swr_ctx)) < 0) {
+#if 0//(LIBAVCODEC_VERSION_MAJOR > 56)
+ avcodec_free_context(&(ost->context));
+#endif
p_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_MOVIE_SAVER, "Failed to initialize the resampling context\n");
return false;
}
void *MOVIE_SAVER::get_audio_frame()
{
#if defined(USE_LIBAV)
- OutputStream *ost = &audio_st;
- AVFrame *frame = ost->tmp_frame;
+ AVFrame *frame = audio_st.tmp_frame;
int j, i;
int16_t *q = (int16_t*)frame->data[0];
int offset = 0;
audio_remain = audio_size;
audio_offset = 0;
}
- for (i = 0; i < ost->st->codec->channels; i++) {
+ int chs;
+ #if 0//(LIBAVCODEC_VERSION_MAJOR > 56)
+ chs = audio_st.context->channels;
+ #else
+ chs = audio_st.st->codec->channels;
+ #endif
+ for (i = 0; i < chs; i++) {
q[offset++] = audio_frame_buf[audio_offset++];
audio_remain -= sizeof(int16_t);
if(audio_remain <= 0) {
//}
}
}
- frame->pts = av_rescale_rnd(ost->next_pts, audio_st.st->codec->sample_rate, audio_sample_rate, AV_ROUND_UP);
+ #if 0//(LIBAVCODEC_VERSION_MAJOR > 56)
+ frame->pts = av_rescale_rnd(audio_st.next_pts, audio_st.context->sample_rate, audio_sample_rate, AV_ROUND_UP);
+ #else
+ frame->pts = av_rescale_rnd(audio_st.next_pts, audio_st.st->codec->sample_rate, audio_sample_rate, AV_ROUND_UP);
+ #endif
//frame->pts = ost->next_pts;
//ost->next_pts += frame->nb_samples;
int got_packet;
int dst_nb_samples;
- av_init_packet(&pkt);
+ #if 0//(LIBAVCODEC_VERSION_MAJOR > 56)
+ c = ost->context;
+ #else
c = ost->st->codec;
-
+ #endif
+ av_init_packet(&pkt);
frame_src = (AVFrame *)get_audio_frame();
//if(req_close) return 1;
if (frame_src == NULL) return 0;
ost->next_pts += dst_nb_samples;
totalAudioFrame++;
}
-
+ #if 0//(LIBAVCODEC_VERSION_MAJOR > 56)
+ got_packet = 0;
+ {
+ ret = avcodec_send_frame(c, frame_dst);
+ if(ret < 0) {
+ if(ret == AVERROR_EOF) {
+ return 0;
+ }
+ return ((ret == AVERROR(EAGAIN)) ? 0 : -1);
+ }
+ while (ret >= 0) {
+ ret = avcodec_receive_packet(c, &pkt);
+ if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
+ return (got_packet || frame_dst) ? 0 : 1;
+ } else if (ret < 0) {
+ p_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_MOVIE_SAVER, "Error while writing audio frame: %s\n",
+ err2str(ret).toLocal8Bit().constData());
+ return -1;
+ }
+ got_packet = 1;
+ pkt.stream_index = 1;
+ int ret2 = this->write_frame((void *)oc, (const void *)&c->time_base, (void *)ost->st, (void *)&pkt);
+ if (ret2 < 0) {
+ p_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_MOVIE_SAVER, "Error while writing audio frame: %s\n", err2str(ret2).toLocal8Bit().constData());
+ return -1;
+ }
+ av_packet_unref(&pkt);
+ }
+ }
+ return (frame_dst || got_packet) ? 0 : 1;
+#else
ret = avcodec_encode_audio2(c, &pkt, frame_dst, &got_packet);
if (ret < 0) {
p_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_MOVIE_SAVER, "Error encoding audio frame: %s\n", err2str(ret).toLocal8Bit().constData());
//}
}
return (frame_dst || got_packet) ? 0 : 1;
+#endif
#else
return 1;
#endif
AVCodecContext *c = (AVCodecContext *)_codec_context;
AVCodec **codec = (AVCodec **)_codec;
- c->sample_fmt = (*codec)->sample_fmts ?
- (*codec)->sample_fmts[0] : AV_SAMPLE_FMT_FLTP;
+ #if 1//(LIBAVCODEC_VERSION_MAJOR <= 56)
+ c->sample_fmt = (*codec)->sample_fmts ? (*codec)->sample_fmts[0] : AV_SAMPLE_FMT_FLTP;
c->bit_rate = audio_bit_rate;
c->sample_rate = audio_sample_rate;
+ #endif
if(c->codec_id == AUDIO_CODEC_AAC) {
c->strict_std_compliance = -2; // For internal AAC
c->global_quality = 100;
c->cutoff = (audio_sample_rate * 3) / 5;
} else {
c->cutoff = audio_sample_rate / 2;
- }
+ }
+ #if 1//(LIBAVCODEC_VERSION_MAJOR <= 56)
if ((*codec)->supported_samplerates) {
c->sample_rate = (*codec)->supported_samplerates[0];
for (int i = 0; (*codec)->supported_samplerates[i]; i++) {
}
}
c->channels = av_get_channel_layout_nb_channels(c->channel_layout);
+ #endif
#endif
}
}
/* Add an output stream. */
-//static void add_stream(OutputStream *ost, AVFormatContext *oc,
-// AVCodec **codec,
-// enum AVCodecID codec_id)
bool MOVIE_SAVER::add_stream(void *_ost, void *_oc,
void **_codec,
uint64_t _codec_id)
{
#if defined(USE_LIBAV)
AVCodecContext *c;
-
OutputStream *ost = (OutputStream *)_ost;
AVFormatContext *oc = (AVFormatContext *)_oc;
AVCodec **codec = (AVCodec **)_codec;
return false;
}
ost->st->id = oc->nb_streams-1;
+#if 0//(LIBAVCODEC_VERSION_MAJOR > 56)
+ ost->context = avcodec_alloc_context3(*codec);
+ if (ost->context == NULL) {
+ p_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_MOVIE_SAVER, "Failed to allocate context for encoding: \n");
+ return false;
+ }
+ AVCodecParameters *cp = ost->st->codecpar;
+ AVRational ratio;
+ ratio.num = 1;
+ ratio.den = 1;
+ switch ((*codec)->type) {
+ case AVMEDIA_TYPE_AUDIO:
+ cp->codec_type = AVMEDIA_TYPE_AUDIO;
+ cp->codec_id = codec_id;
+ cp->format = (*codec)->sample_fmts ? (*codec)->sample_fmts[0] : AV_SAMPLE_FMT_FLTP;
+ cp->bit_rate = audio_bit_rate;
+ cp->channel_layout = AV_CH_LAYOUT_STEREO;
+ cp->channels = 2;
+ cp->sample_rate = audio_sample_rate;
+ cp->frame_size = 1024;
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ cp->codec_type = AVMEDIA_TYPE_VIDEO;
+ cp->codec_id = codec_id;
+ cp->format = STREAM_PIX_FMT;
+ cp->bit_rate = video_bit_rate;
+ cp->width = video_geometry.width();
+ cp->height = video_geometry.height();
+// cp->profile = ;
+// cp->level = ;
+ cp->sample_aspect_ratio = ratio;
+ cp->field_order = AV_FIELD_PROGRESSIVE;
+ break;
+ default:
+ break;
+ }
+ avcodec_parameters_to_context(ost->context, cp);
+ c = ost->context;
+#else
c = ost->st->codec;
-
+#endif
switch ((*codec)->type) {
case AVMEDIA_TYPE_AUDIO:
setup_audio(c, (void **)codec);
ost->st->time_base = (AVRational){ 1, c->sample_rate };
break;
case AVMEDIA_TYPE_VIDEO:
+ #if 1//(LIBAVCODEC_VERSION_MAJOR <= 56)
c->codec_id = codec_id;
c->bit_rate = video_bit_rate;
// See:
/* Resolution must be a multiple of two. */
c->width = video_geometry.width();
c->height = video_geometry.height();
+ #endif
c->thread_count = video_encode_threads;
/* timebase: This is the fundamental unit of time (in seconds) in terms
c->time_base = ost->st->time_base;
//c->gop_size = rec_fps; /* emit one intra frame every one second */
+ #if 1//(LIBAVCODEC_VERSION_MAJOR <= 56)
c->pix_fmt = STREAM_PIX_FMT;
+ #endif
if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
/* just for testing, we also add B frames */
c->max_b_frames = 2;
void MOVIE_SAVER::close_stream(void *_oc, void *_ost)
{
#if defined(USE_LIBAV)
- AVFormatContext *oc = (AVFormatContext *)_oc;
OutputStream *ost = (OutputStream *)_ost;
+ #if 0//(LIBAVCODEC_VERSION_MAJOR > 56)
+ avcodec_close(ost->context);
+ while(avcodec_is_open(ost->context) != 0) { this->msleep(5);}
+ #else
avcodec_close(ost->st->codec);
while(avcodec_is_open(ost->st->codec) != 0) { this->msleep(5);}
+ #endif
av_frame_free(&ost->frame);
av_frame_free(&ost->tmp_frame);
sws_freeContext(ost->sws_ctx);
swr_free(&ost->swr_ctx);
+ #if 0//(LIBAVCODEC_VERSION_MAJOR > 56)
+ avcodec_free_context(&(ost->context));
+ #endif
#endif
}
memset(&audio_st, 0x00, sizeof(audio_st));
/* Initialize libavcodec, and register all codecs and formats. */
+#if 1//(LIBAVCODEC_VERSION_MAJOR <= 56)
av_register_all();
+#endif
{
QString value;
/* Add the audio and video streams using the default format codecs
* and initialize the codecs. */
if (fmt->video_codec != AV_CODEC_ID_NONE) {
+
if(!add_stream((void *)&video_st, (void *)oc, (void **)&video_codec, (uint64_t)fmt->video_codec)) goto _err_final;
have_video = 1;
encode_video = 1;
video_offset = 0;
}
}
-
+ int result = 0;
+#if 0//(LIBAVCODEC_VERSION_MAJOR > 56)
+ if(audio_st.context != NULL) {
+ if(video_st.context != NULL) {
+ result = av_compare_ts(video_st.next_pts, video_st.context->time_base,
+ audio_st.next_pts, audio_st.context->time_base);
+ } else {
+ result = 1;
+ }
+ } else {
+ result = -1;
+ }
+#else
+ result = av_compare_ts(video_st.next_pts, video_st.st->codec->time_base,
+ audio_st.next_pts, audio_st.st->codec->time_base);
+#endif
if ((n_encode_video == 0) &&
- ((n_encode_audio != 0) || av_compare_ts(video_st.next_pts, video_st.st->codec->time_base,
- audio_st.next_pts, audio_st.st->codec->time_base) <= 0)) {
+ ((n_encode_audio != 0) || (result <= 0))) {
n_encode_video = write_video_frame();
if(n_encode_video < 0) break;
} else {
if (have_video) {
close_stream(oc, &video_st);
}
- if (have_audio)
+ if (have_audio) {
close_stream(oc, &audio_st);
+ }
have_video = have_audio = 0;
av_write_trailer(oc);
void MOVIE_SAVER::setup_mpeg4(void *_codec)
{
-#if defined(USE_LIBAV)
+#if defined(USE_LIBAV)
AVCodecContext *c = (AVCodecContext *)_codec;
c->qmin = p_config->video_mpeg4_minq;
c->qmax = p_config->video_mpeg4_maxq;
AVDictionary *opt_arg = raw_options_list;
OutputStream *ost = &video_st;
AVCodec *codec = video_codec;
- AVFormatContext *oc = output_context;
- AVCodecContext *c = ost->st->codec;
+ AVCodecContext *c;
AVDictionary *opt = NULL;
+#if 0//(LIBAVCODEC_VERSION_MAJOR > 56)
+ c = ost->context;
+#else
+ c = ost->st->codec;
+#endif
av_dict_copy(&opt, opt_arg, 0);
{
#if defined(USE_LIBAV)
OutputStream *ost = &video_st;
- AVCodecContext *c = ost->st->codec;
+ AVCodecContext *c;
+#if 0//(LIBAVCODEC_VERSION_MAJOR > 56)
+ c = ost->context;
+#else
+ c = ost->st->codec;
+#endif
//if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
/* as we only generate a YUV420P picture, we must convert it
int got_packet = 0;
AVPacket pkt = { 0 };
+#if 0//(LIBAVCODEC_VERSION_MAJOR > 56)
+ c = ost->context;
+#else
c = ost->st->codec;
+#endif
frame = (AVFrame *)get_video_frame();
av_init_packet(&pkt);
-
/* encode the image */
frame->pts = totalDstFrame;
//got_packet = 1;
//while(got_packet) {
+#if 0//(LIBAVCODEC_VERSION_MAJOR > 56)
+ if(frame != NULL) {
+ ret = avcodec_send_frame(c, frame);
+ totalDstFrame++;
+ if(ret < 0) {
+ if(ret == AVERROR_EOF) {
+ return 0;
+ }
+ return ((ret == AVERROR(EAGAIN)) ? 0 : -1);
+ }
+ while (ret >= 0) {
+ ret = avcodec_receive_packet(c, &pkt);
+ if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
+ return (frame || got_packet) ? 0 : 1;
+ } else if (ret < 0) {
+ p_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_MOVIE_SAVER, "Error while writing video frame: %s\n",
+ err2str(ret).toLocal8Bit().constData());
+ return -1;
+ }
+ pkt.stream_index = 0;
+ int ret2 = this->write_frame((void *)oc, (const void *)&c->time_base, (void *)ost->st, (void *)&pkt);
+ if (ret2 < 0) {
+ p_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_MOVIE_SAVER, "Error while writing video frame: %s\n", err2str(ret2).toLocal8Bit().constData());
+ return -1;
+ }
+ got_packet = 1;
+ av_packet_unref(&pkt);
+ }
+ }
+ return (frame || got_packet) ? 0 : 1;
+#else
ret = avcodec_encode_video2(c, &pkt, frame, &got_packet);
- //if(!got_packet) break;
if (ret < 0) {
p_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_MOVIE_SAVER, "Error encoding video frame: %s\n", err2str(ret).toLocal8Bit().constData());
return -1;
}
+ //if(!got_packet) break;
totalDstFrame++;
if (got_packet) {
ret = this->write_frame((void *)oc, (const void *)&c->time_base, (void *)ost->st, (void *)&pkt);
} else {
ret = 0;
}
-
if (ret < 0) {
p_logger->debug_log(CSP_LOG_INFO, CSP_LOG_TYPE_MOVIE_SAVER, "Error while writing video frame: %s\n", err2str(ret).toLocal8Bit().constData());
return -1;
}
+
//}
//if(frame) {
// char buf[256];
// AGAR_DebugLog(AGAR_LOG_DEBUG, "Movie: Write video to file. sec=%s", s);
//}
return (frame || got_packet) ? 0 : 1;
+#endif
#else
return 1;
#endif
_data_size = 0;
_dataptr = 0;
/* register all formats and codecs */
+#if (LIBAVCODEC_VERSION_MAJOR <= 56)
av_register_all();
+#endif
/* open input file, and allocate format context */
if (avformat_open_input(&fmt_ctx, _filename.toLocal8Bit().constData(), NULL, NULL) < 0) {
int SOUND_LOADER::decode_audio(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame,
int *got_frame)
{
- int ch;
int ret = 0;
#if (LIBAVCODEC_VERSION_MAJOR > 56)
/* send the packet with the compressed data to the decoder */