From 83437c365689d293593e7643a119ef9b82f69dcc Mon Sep 17 00:00:00 2001 From: BPanther Date: Tue, 4 Feb 2020 22:20:44 +0100 Subject: [PATCH] patch for sh4 and actual ffmpeg versions (thx DBoxOldie) --- libeplayer3-sh4/include/input.h | 12 +++ libeplayer3-sh4/include/writer.h | 20 +++++ libeplayer3-sh4/input.cpp | 148 +++++++++++++++++++++---------- libeplayer3-sh4/output.cpp | 30 +++---- libeplayer3-sh4/writer/divx.cpp | 4 +- libeplayer3-sh4/writer/h264.cpp | 8 +- libeplayer3-sh4/writer/pcm.cpp | 40 ++++++++- libeplayer3-sh4/writer/vc1.cpp | 20 ++--- libeplayer3-sh4/writer/wmv.cpp | 18 ++-- libspark/video.cpp | 81 ++++++++++++++--- 10 files changed, 281 insertions(+), 100 deletions(-) diff --git a/libeplayer3-sh4/include/input.h b/libeplayer3-sh4/include/input.h index d27e0fa..434aa23 100644 --- a/libeplayer3-sh4/include/input.h +++ b/libeplayer3-sh4/include/input.h @@ -38,6 +38,14 @@ extern "C" { #include } +#if (LIBAVFORMAT_VERSION_INT > AV_VERSION_INT( 57,25,100 )) +#define EPLAYER_MAX_CODECS 16 +struct CodecList +{ + AVCodecContext *codec; +}; +#endif + class Player; class Track; @@ -63,6 +71,9 @@ class Input Player *player; AVFormatContext *avfc; +#if (LIBAVFORMAT_VERSION_INT > AV_VERSION_INT( 57,25,100 )) + CodecList codecs[EPLAYER_MAX_CODECS]; +#endif uint64_t readCount; int64_t calcPts(AVStream * stream, int64_t pts); @@ -85,6 +96,7 @@ class Input bool GetMetadata(std::vector &keys, std::vector &values); bool GetReadCount(uint64_t &readcount); AVFormatContext *GetAVFormatContext(); + AVCodecContext *GetCodecContext(unsigned int index); void ReleaseAVFormatContext(); }; diff --git a/libeplayer3-sh4/include/writer.h b/libeplayer3-sh4/include/writer.h index 359223b..19795ea 100644 --- a/libeplayer3-sh4/include/writer.h +++ b/libeplayer3-sh4/include/writer.h @@ -37,6 +37,26 @@ extern "C" { #define AV_CODEC_ID_INJECTPCM AV_CODEC_ID_PCM_S16LE +/* wrapper */ +#if (LIBAVFORMAT_VERSION_INT > AV_VERSION_INT( 57,25,100 )) +static AVCodecParameters __attribute__ ((unused)) *get_codecpar(AVStream *stream) +{ + return stream->codecpar; +} +#else +static AVCodecContext __attribute__ ((unused)) *get_codecpar(AVStream *stream) +{ + return stream->codec; +} +#endif + +#if (LIBAVCODEC_VERSION_MAJOR > 55) +#define av_free_packet av_packet_unref +#else +#define av_packet_unref av_free_packet +#endif +/* end wrapper */ + class Player; class Writer diff --git a/libeplayer3-sh4/input.cpp b/libeplayer3-sh4/input.cpp index 46208aa..77f7d23 100644 --- a/libeplayer3-sh4/input.cpp +++ b/libeplayer3-sh4/input.cpp @@ -54,6 +54,10 @@ Input::Input() seek_avts_abs = INT64_MIN; seek_avts_rel = 0; abortPlayback = false; +#if (LIBAVFORMAT_VERSION_INT > AV_VERSION_INT( 57,25,100 )) + for (int n = 0;n < EPLAYER_MAX_CODECS;n++) + codecs[n].codec = NULL; +#endif } Input::~Input() @@ -108,6 +112,43 @@ static void logprintf(const char *format, ...) va_end(ap); } +AVCodecContext *Input::GetCodecContext(unsigned int index) +{ +#if (LIBAVFORMAT_VERSION_INT > AV_VERSION_INT( 57,25,100 )) + if (codecs[index].codec) { + return codecs[index].codec; + } + AVCodec *codec = avcodec_find_decoder(avfc->streams[index]->codecpar->codec_id); + codecs[index].codec = avcodec_alloc_context3(codec); + if (!codecs[index].codec) { + fprintf(stderr, "context3 alloc for stream %d failed\n", (int)index); + return NULL; + } + if (avcodec_parameters_to_context(codecs[index].codec, avfc->streams[index]->codecpar) < 0) { + fprintf(stderr, "copy parameters to codec context for stream %d failed\n", (int)index); + avcodec_free_context(&codecs[index].codec); + return NULL; + } + if (!codec) { + fprintf(stderr, "decoder for codec_id:(0x%X) stream:(%d) not found\n", avfc->streams[index]->codecpar->codec_id, (int)index);; + return codecs[index].codec; + } + else + { + fprintf(stderr, "decoder for codec_id:(0x%X) stream:(%d) found\n", avfc->streams[index]->codecpar->codec_id, (int)index);; + } + int err = avcodec_open2(codecs[index].codec, codec, NULL); + if (averror(err, avcodec_open2)) { + fprintf(stderr, "open codec context for stream:(%d) failed}n", (int)index); + avcodec_free_context(&codecs[index].codec); + return NULL; + } + return codecs[index].codec; +#else + return avfc->streams[index]->codec; +#endif +} + bool Input::Play() { hasPlayThreadStarted = 1; @@ -182,9 +223,11 @@ bool Input::Play() restart_audio_resampling = true; // clear streams - for (unsigned int i = 0; i < avfc->nb_streams; i++) - if (avfc->streams[i]->codec && avfc->streams[i]->codec->codec) - avcodec_flush_buffers(avfc->streams[i]->codec); + for (unsigned int i = 0; i < avfc->nb_streams; i++) { + AVCodecContext *avcctx = GetCodecContext(i); + if (avcctx && avcctx->codec) + avcodec_flush_buffers(avcctx); + } player->output.ClearAudio(); player->output.ClearVideo(); } @@ -194,19 +237,18 @@ bool Input::Play() int err = av_read_frame(avfc, &packet); if (err == AVERROR(EAGAIN)) { -#if (LIBAVFORMAT_VERSION_MAJOR == 57 && LIBAVFORMAT_VERSION_MINOR == 25) av_packet_unref(&packet); -#else - av_free_packet(&packet); -#endif continue; } - if (averror(err, av_read_frame)) // EOF? + if (averror(err, av_read_frame)) { // EOF? + av_packet_unref(&packet); break; // while + } player->readCount += packet.size; AVStream *stream = avfc->streams[packet.stream_index]; + AVCodecContext *avcctx = GetCodecContext((unsigned int)stream->index); Track *_videoTrack = videoTrack; Track *_audioTrack = audioTrack; Track *_subtitleTrack = subtitleTrack; @@ -228,19 +270,19 @@ bool Input::Play() } audioSeen = true; } else if (_subtitleTrack && (_subtitleTrack->stream == stream)) { - if (stream->codec->codec) { + if (avcctx->codec) { AVSubtitle sub; memset(&sub, 0, sizeof(sub)); int got_sub_ptr = 0; - err = avcodec_decode_subtitle2(stream->codec, &sub, &got_sub_ptr, &packet); + err = avcodec_decode_subtitle2(avcctx, &sub, &got_sub_ptr, &packet); averror(err, avcodec_decode_subtitle2); if (got_sub_ptr && sub.num_rects > 0) { switch (sub.rects[0]->type) { case SUBTITLE_TEXT: // FIXME? case SUBTITLE_ASS: - dvbsub_ass_write(stream->codec, &sub, _subtitleTrack->pid); + dvbsub_ass_write(avcctx, &sub, _subtitleTrack->pid); break; case SUBTITLE_BITMAP: { int64_t pts = calcPts(stream, packet.pts); @@ -258,11 +300,8 @@ bool Input::Play() teletext_write(_teletextTrack->pid, packet.data + 1, packet.size - 1); } -#if (LIBAVFORMAT_VERSION_MAJOR == 57 && LIBAVFORMAT_VERSION_MINOR == 25) av_packet_unref(&packet); -#else - av_free_packet(&packet); -#endif + } /* while */ if (player->abortRequested) @@ -286,6 +325,7 @@ bool Input::Play() return res; } +#if LIBAVCODEC_VERSION_MAJOR < 58 static int lock_callback(void **mutex, enum AVLockOp op) { switch (op) { @@ -306,6 +346,7 @@ static int lock_callback(void **mutex, enum AVLockOp op) return -1; } } +#endif bool Input::ReadSubtitle(const char *filename, const char *format, int pid) { @@ -332,8 +373,20 @@ bool Input::ReadSubtitle(const char *filename, const char *format, int pid) return false; } - AVCodecContext *c = subavfc->streams[0]->codec; - AVCodec *codec = avcodec_find_decoder(c->codec_id); + AVCodecContext *c = NULL; + AVCodec *codec = NULL; +#if (LIBAVFORMAT_VERSION_INT < AV_VERSION_INT( 57,25,101 )) + c = subavfc->streams[0]->codec; +#else + c = avcodec_alloc_context3(codec); + if (avcodec_parameters_to_context(c, subavfc->streams[0]->codecpar) < 0) { + avcodec_free_context(&c); + avformat_close_input(&subavfc); + avformat_free_context(subavfc); + return false; + } +#endif + codec = avcodec_find_decoder(c->codec_id); if (!codec) { avformat_free_context(subavfc); return false; @@ -355,13 +408,12 @@ bool Input::ReadSubtitle(const char *filename, const char *format, int pid) avcodec_decode_subtitle2(c, &sub, &got_sub, &packet); if (got_sub) dvbsub_ass_write(c, &sub, pid); -#if (LIBAVFORMAT_VERSION_MAJOR == 57 && LIBAVFORMAT_VERSION_MINOR == 25) av_packet_unref(&packet); -#else - av_free_packet(&packet); -#endif } avcodec_close(c); +#if (LIBAVFORMAT_VERSION_INT > AV_VERSION_INT( 57,25,100 )) + avcodec_free_context(&c); +#endif avformat_close_input(&subavfc); avformat_free_context(subavfc); @@ -388,7 +440,9 @@ bool Input::Init(const char *filename, std::string headers) { bool find_info = true; abortPlayback = false; +#if LIBAVCODEC_VERSION_MAJOR < 58 av_lockmgr_register(lock_callback); +#endif #if ENABLE_LOGGING av_log_set_flags(AV_LOG_SKIP_REPEATED); av_log_set_level(AV_LOG_INFO); @@ -414,8 +468,10 @@ bool Input::Init(const char *filename, std::string headers) fprintf(stderr, "%s %s %d: %s\n", FILENAME, __func__, __LINE__, filename); } +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100) avcodec_register_all(); av_register_all(); +#endif avformat_network_init(); videoTrack = NULL; @@ -452,10 +508,8 @@ again: avfc->iformat->flags |= AVFMT_SEEK_TO_PTS; avfc->flags = AVFMT_FLAG_GENPTS; if (player->noprobe) { -#if (LIBAVFORMAT_VERSION_MAJOR < 55) || \ - (LIBAVFORMAT_VERSION_MAJOR == 55 && LIBAVFORMAT_VERSION_MINOR < 43) || \ - (LIBAVFORMAT_VERSION_MAJOR == 55 && LIBAVFORMAT_VERSION_MINOR == 43 && LIBAVFORMAT_VERSION_MICRO < 100) || \ - (LIBAVFORMAT_VERSION_MAJOR == 57 && LIBAVFORMAT_VERSION_MINOR == 25) +#if (LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(55, 43, 100)) || \ + (LIBAVFORMAT_VERSION_INT > AV_VERSION_INT(57, 25, 0)) avfc->max_analyze_duration = 1; #else avfc->max_analyze_duration2 = 1; @@ -527,13 +581,15 @@ bool Input::UpdateTracks() for (unsigned int n = 0; n < avfc->nb_streams; n++) { AVStream *stream = avfc->streams[n]; + AVCodecContext *avcctx = GetCodecContext(n); + Track track; track.stream = stream; AVDictionaryEntry *lang = av_dict_get(stream->metadata, "language", NULL, 0); track.title = lang ? lang->value : ""; if (!use_index_as_pid) - switch (stream->codec->codec_type) { + switch (avcctx->codec_type) { case AVMEDIA_TYPE_VIDEO: case AVMEDIA_TYPE_AUDIO: case AVMEDIA_TYPE_SUBTITLE: @@ -546,14 +602,14 @@ bool Input::UpdateTracks() track.pid = use_index_as_pid ? n + 1: stream->id; track.ac3flags = 0; - switch (stream->codec->codec_type) { + switch (avcctx->codec_type) { case AVMEDIA_TYPE_VIDEO: player->manager.addVideoTrack(track); if (!videoTrack) videoTrack = player->manager.getVideoTrack(track.pid); break; case AVMEDIA_TYPE_AUDIO: - switch(stream->codec->codec_id) { + switch(avcctx->codec_id) { case AV_CODEC_ID_MP2: track.ac3flags = 1; break; @@ -567,10 +623,10 @@ bool Input::UpdateTracks() track.ac3flags = 4; break; case AV_CODEC_ID_AAC: { - unsigned int extradata_size = stream->codec->extradata_size; + unsigned int extradata_size = avcctx->extradata_size; unsigned int object_type = 2; if(extradata_size >= 2) - object_type = stream->codec->extradata[0] >> 3; + object_type = avcctx->extradata[0] >> 3; if (extradata_size <= 1 || object_type == 1 || object_type == 5) { fprintf(stderr, "use resampling for AAC\n"); track.ac3flags = 6; @@ -597,10 +653,10 @@ bool Input::UpdateTracks() audioTrack = player->manager.getAudioTrack(track.pid); break; case AVMEDIA_TYPE_SUBTITLE: - if (stream->codec->codec_id == AV_CODEC_ID_DVB_TELETEXT) { + if (avcctx->codec_id == AV_CODEC_ID_DVB_TELETEXT) { std::string l = lang ? lang->value : ""; - uint8_t *data = stream->codec->extradata; - int size = stream->codec->extradata_size; + uint8_t *data = avcctx->extradata; + int size = avcctx->extradata_size; if (size > 0 && 2 * size - 1 == (int) l.length()) for (int i = 0; i < size; i += 2) { track.title = l.substr(i * 2, 3); @@ -610,22 +666,22 @@ bool Input::UpdateTracks() player->manager.addTeletextTrack(track); } } else { - if (!stream->codec->codec) { - stream->codec->codec = avcodec_find_decoder(stream->codec->codec_id); - if (!stream->codec->codec) + if (!avcctx->codec) { + avcctx->codec = avcodec_find_decoder(avcctx->codec_id); + if (!avcctx->codec) fprintf(stderr, "avcodec_find_decoder failed for subtitle track %d\n", n); else { - int err = avcodec_open2(stream->codec, stream->codec->codec, NULL); + int err = avcodec_open2(avcctx, avcctx->codec, NULL); if (averror(err, avcodec_open2)) - stream->codec->codec = NULL; + avcctx->codec = NULL; } } - if (stream->codec->codec) + if (avcctx->codec) player->manager.addSubtitleTrack(track); } break; default: - fprintf(stderr, "not handled or unknown codec_type %d\n", stream->codec->codec_type); + fprintf(stderr, "not handled or unknown codec_type %d\n", avcctx->codec_type); break; } } @@ -657,8 +713,14 @@ bool Input::Stop() if (avfc) { OpenThreads::ScopedLock lock(mutex); - for (unsigned int i = 0; i < avfc->nb_streams; i++) + for (unsigned int i = 0; i < avfc->nb_streams; i++) { +#if (LIBAVFORMAT_VERSION_INT > AV_VERSION_INT( 57,25,100 )) + if (codecs[i].codec) + avcodec_free_context(&codecs[i].codec); +#else avcodec_close(avfc->streams[i]->codec); +#endif + } avformat_close_input(&avfc); } @@ -763,11 +825,7 @@ bool Input::GetMetadata(std::vector &keys, std::vector fwrite(pkt->data, pkt->size, 1, cover_art); fclose(cover_art); } -#if (LIBAVFORMAT_VERSION_MAJOR == 57 && LIBAVFORMAT_VERSION_MINOR == 25) av_packet_unref(pkt); -#else - av_free_packet(pkt); -#endif break; } } diff --git a/libeplayer3-sh4/output.cpp b/libeplayer3-sh4/output.cpp index 11e4eb7..1d53864 100644 --- a/libeplayer3-sh4/output.cpp +++ b/libeplayer3-sh4/output.cpp @@ -127,22 +127,20 @@ bool Output::Play() OpenThreads::ScopedLock v_lock(videoMutex); OpenThreads::ScopedLock a_lock(audioMutex); - AVCodecContext *avcc; - - if (videoTrack && videoTrack->stream && videofd > -1 && (avcc = videoTrack->stream->codec)) { - videoWriter = Writer::GetWriter(avcc->codec_id, avcc->codec_type, videoTrack->ac3flags); + if (videoTrack && videoTrack->stream && videofd > -1 && get_codecpar(videoTrack->stream)) { + videoWriter = Writer::GetWriter(get_codecpar(videoTrack->stream)->codec_id, get_codecpar(videoTrack->stream)->codec_type, videoTrack->ac3flags); videoWriter->Init(videofd, videoTrack->stream, player); - if (dioctl(videofd, VIDEO_SET_ENCODING, videoWriter->GetVideoEncoding(avcc->codec_id)) + if (dioctl(videofd, VIDEO_SET_ENCODING, videoWriter->GetVideoEncoding(get_codecpar(videoTrack->stream)->codec_id)) || dioctl(videofd, VIDEO_PLAY, NULL)) ret = false; } - if (audioTrack && audioTrack->stream && audiofd > -1 && (avcc = audioTrack->stream->codec)) { - audioWriter = Writer::GetWriter(avcc->codec_id, avcc->codec_type, audioTrack->ac3flags); + if (audioTrack && audioTrack->stream && audiofd > -1 && get_codecpar(audioTrack->stream)) { + audioWriter = Writer::GetWriter(get_codecpar(audioTrack->stream)->codec_id, get_codecpar(audioTrack->stream)->codec_type, audioTrack->ac3flags); audioWriter->Init(audiofd, audioTrack->stream, player); audio_encoding_t audioEncoding = AUDIO_ENCODING_LPCMA; if (audioTrack->ac3flags != 6) - audioEncoding = audioWriter->GetAudioEncoding(avcc->codec_id); + audioEncoding = audioWriter->GetAudioEncoding(get_codecpar(audioTrack->stream)->codec_id); if (dioctl(audiofd, AUDIO_SET_ENCODING, audioEncoding) || dioctl(audiofd, AUDIO_PLAY, NULL)) ret = false; @@ -311,15 +309,14 @@ bool Output::SwitchAudio(Track *track) } audioTrack = track; if (track->stream) { - AVCodecContext *avcc = track->stream->codec; - if (!avcc) + if (!get_codecpar(audioTrack->stream)) return false; - audioWriter = Writer::GetWriter(avcc->codec_id, avcc->codec_type, audioTrack->ac3flags); + audioWriter = Writer::GetWriter(get_codecpar(audioTrack->stream)->codec_id, get_codecpar(audioTrack->stream)->codec_type, audioTrack->ac3flags); audioWriter->Init(audiofd, audioTrack->stream, player); if (audiofd > -1) { audio_encoding_t audioEncoding = AUDIO_ENCODING_LPCMA; if (audioTrack->ac3flags != 6) - audioEncoding = Writer::GetAudioEncoding(avcc->codec_id); + audioEncoding = Writer::GetAudioEncoding(get_codecpar(audioTrack->stream)->codec_id); dioctl(audiofd, AUDIO_SET_ENCODING, audioEncoding); dioctl(audiofd, AUDIO_PLAY, NULL); } @@ -338,13 +335,12 @@ bool Output::SwitchVideo(Track *track) } videoTrack = track; if (track->stream) { - AVCodecContext *avcc = track->stream->codec; - if (!avcc) + if (!get_codecpar(videoTrack->stream)) return false; - videoWriter = Writer::GetWriter(avcc->codec_id, avcc->codec_type, videoTrack->type); + videoWriter = Writer::GetWriter(get_codecpar(videoTrack->stream)->codec_id, get_codecpar(videoTrack->stream)->codec_type, videoTrack->type); videoWriter->Init(videofd, videoTrack->stream, player); if (videofd > -1) { - dioctl(videofd, VIDEO_SET_ENCODING, Writer::GetVideoEncoding(avcc->codec_id)); + dioctl(videofd, VIDEO_SET_ENCODING, Writer::GetVideoEncoding(get_codecpar(videoTrack->stream)->codec_id)); dioctl(videofd, VIDEO_PLAY, NULL); } } @@ -353,7 +349,7 @@ bool Output::SwitchVideo(Track *track) bool Output::Write(AVStream *stream, AVPacket *packet, int64_t pts) { - switch (stream->codec->codec_type) { + switch (get_codecpar(stream)->codec_type) { case AVMEDIA_TYPE_VIDEO: { OpenThreads::ScopedLock v_lock(videoMutex); return videofd > -1 && videoWriter && videoWriter->Write(packet, pts); diff --git a/libeplayer3-sh4/writer/divx.cpp b/libeplayer3-sh4/writer/divx.cpp index 2138dc1..f3a2bbd 100644 --- a/libeplayer3-sh4/writer/divx.cpp +++ b/libeplayer3-sh4/writer/divx.cpp @@ -89,8 +89,8 @@ bool WriterDIVX::Write(AVPacket *packet, int64_t pts) iov[ic++].iov_len = FakeHeaderLength; if (initialHeader) { - iov[ic].iov_base = stream->codec->extradata; - iov[ic++].iov_len = stream->codec->extradata_size; + iov[ic].iov_base = get_codecpar(stream)->extradata; + iov[ic++].iov_len = get_codecpar(stream)->extradata_size; initialHeader = false; } iov[ic].iov_base = packet->data; diff --git a/libeplayer3-sh4/writer/h264.cpp b/libeplayer3-sh4/writer/h264.cpp index fee1d96..e2c3183 100644 --- a/libeplayer3-sh4/writer/h264.cpp +++ b/libeplayer3-sh4/writer/h264.cpp @@ -83,9 +83,9 @@ bool WriterH264::Write(AVPacket *packet, int64_t pts) unsigned int len = 0; if (initialHeader) { initialHeader = false; - iov[ic].iov_base = stream->codec->extradata; - iov[ic++].iov_len = stream->codec->extradata_size; - len += stream->codec->extradata_size; + iov[ic].iov_base = get_codecpar(stream)->extradata; + iov[ic++].iov_len = get_codecpar(stream)->extradata_size; + len += get_codecpar(stream)->extradata_size; } iov[ic].iov_base = packet->data; iov[ic++].iov_len = packet->size; @@ -104,7 +104,7 @@ bool WriterH264::Write(AVPacket *packet, int64_t pts) // convert NAL units without sync byte sequence to byte-stream format if (initialHeader) { - avcC_t *avcCHeader = (avcC_t *) stream->codec->extradata; + avcC_t *avcCHeader = (avcC_t *) get_codecpar(stream)->extradata; if (!avcCHeader) { fprintf(stderr, "stream->codec->extradata == NULL\n"); diff --git a/libeplayer3-sh4/writer/pcm.cpp b/libeplayer3-sh4/writer/pcm.cpp index 372a215..7c06dd0 100644 --- a/libeplayer3-sh4/writer/pcm.cpp +++ b/libeplayer3-sh4/writer/pcm.cpp @@ -236,7 +236,7 @@ bool WriterPCM::Write(AVPacket *packet, int64_t pts) return true; } - AVCodecContext *c = stream->codec; + AVCodecContext *c = player->input.GetCodecContext((unsigned int)stream->index); if (restart_audio_resampling) { restart_audio_resampling = false; @@ -251,6 +251,7 @@ bool WriterPCM::Write(AVPacket *packet, int64_t pts) decoded_frame = NULL; } +#if (LIBAVFORMAT_VERSION_INT < AV_VERSION_INT( 57,25,101 )) AVCodec *codec = avcodec_find_decoder(c->codec_id); if (!codec) { fprintf(stderr, "%s %d: avcodec_find_decoder(%llx)\n", __func__, __LINE__, (unsigned long long) c->codec_id); @@ -261,6 +262,7 @@ bool WriterPCM::Write(AVPacket *packet, int64_t pts) fprintf(stderr, "%s %d: avcodec_open2 failed\n", __func__, __LINE__); return false; } +#endif } if (!swr) { @@ -313,7 +315,6 @@ bool WriterPCM::Write(AVPacket *packet, int64_t pts) unsigned int packet_size = packet->size; while (packet_size > 0 || (!packet_size && !packet->data)) { - int got_frame = 0; if (!decoded_frame) { if (!(decoded_frame = av_frame_alloc())) { @@ -323,6 +324,9 @@ bool WriterPCM::Write(AVPacket *packet, int64_t pts) } else av_frame_unref(decoded_frame); +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57,37,100) + int got_frame = 0; + int len = avcodec_decode_audio4(c, decoded_frame, &got_frame, packet); if (len < 0) { restart_audio_resampling = true; @@ -337,8 +341,37 @@ bool WriterPCM::Write(AVPacket *packet, int64_t pts) break; continue; } +#else + int ret = avcodec_send_packet(c, packet); + if (ret < 0) { + if (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) { + restart_audio_resampling = true; + break; + } + } + if (ret >= 0) { + packet_size = 0; + } + ret = avcodec_receive_frame(c, decoded_frame); + if (ret < 0) { + if (ret == AVERROR_EOF) { + restart_audio_resampling = true; + break; + } + if (ret != AVERROR(EAGAIN)) { + break; + } + else { + continue; + } + } +#endif +#if (LIBAVUTIL_VERSION_MAJOR < 54) pts = player->input.calcPts(stream, av_frame_get_best_effort_timestamp(decoded_frame)); +#else + pts = player->input.calcPts(stream, decoded_frame->best_effort_timestamp); +#endif int in_samples = decoded_frame->nb_samples; int out_samples = av_rescale_rnd(swr_get_delay(swr, c->sample_rate) + in_samples, out_sample_rate, c->sample_rate, AV_ROUND_UP); @@ -360,6 +393,9 @@ bool WriterPCM::Write(AVPacket *packet, int64_t pts) break; } } + + av_frame_free(&decoded_frame); + return !packet_size; } diff --git a/libeplayer3-sh4/writer/vc1.cpp b/libeplayer3-sh4/writer/vc1.cpp index 34ef182..7d7a0bb 100644 --- a/libeplayer3-sh4/writer/vc1.cpp +++ b/libeplayer3-sh4/writer/vc1.cpp @@ -107,14 +107,14 @@ bool WriterVC1::Write(AVPacket *packet, int64_t pts) PesPtr += WMV3_PRIVATE_DATA_LENGTH; /* Metadata Header Struct A */ - *PesPtr++ = (stream->codec->height >> 0) & 0xff; - *PesPtr++ = (stream->codec->height >> 8) & 0xff; - *PesPtr++ = (stream->codec->height >> 16) & 0xff; - *PesPtr++ = stream->codec->height >> 24; - *PesPtr++ = (stream->codec->width >> 0) & 0xff; - *PesPtr++ = (stream->codec->width >> 8) & 0xff; - *PesPtr++ = (stream->codec->width >> 16) & 0xff; - *PesPtr++ = stream->codec->width >> 24; + *PesPtr++ = (get_codecpar(stream)->height >> 0) & 0xff; + *PesPtr++ = (get_codecpar(stream)->height >> 8) & 0xff; + *PesPtr++ = (get_codecpar(stream)->height >> 16) & 0xff; + *PesPtr++ = get_codecpar(stream)->height >> 24; + *PesPtr++ = (get_codecpar(stream)->width >> 0) & 0xff; + *PesPtr++ = (get_codecpar(stream)->width >> 8) & 0xff; + *PesPtr++ = (get_codecpar(stream)->width >> 16) & 0xff; + *PesPtr++ = get_codecpar(stream)->width >> 24; PesPtr += 12; /* Skip flag word and Struct B first 8 bytes */ @@ -132,8 +132,8 @@ bool WriterVC1::Write(AVPacket *packet, int64_t pts) /* For VC1 the codec private data is a standard vc1 sequence header so we just copy it to the output */ iov[0].iov_base = PesHeader; - iov[1].iov_base = stream->codec->extradata; - iov[1].iov_len = stream->codec->extradata_size; + iov[1].iov_base = get_codecpar(stream)->extradata; + iov[1].iov_len = get_codecpar(stream)->extradata_size; iov[0].iov_len = InsertPesHeader(PesHeader, iov[1].iov_len, VC1_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0); if (writev(fd, iov, 2) < 0) return false; diff --git a/libeplayer3-sh4/writer/wmv.cpp b/libeplayer3-sh4/writer/wmv.cpp index ecc516e..f74a998 100644 --- a/libeplayer3-sh4/writer/wmv.cpp +++ b/libeplayer3-sh4/writer/wmv.cpp @@ -88,20 +88,20 @@ bool WriterWMV::Write(AVPacket *packet, int64_t pts) PesPtr += METADATA_STRUCT_C_START; uint8_t privateData[WMV3_PRIVATE_DATA_LENGTH] = { 0 }; - memcpy(privateData, stream->codec->extradata, stream->codec->extradata_size > WMV3_PRIVATE_DATA_LENGTH ? WMV3_PRIVATE_DATA_LENGTH : stream->codec->extradata_size); + memcpy(privateData, get_codecpar(stream)->extradata, get_codecpar(stream)->extradata_size > WMV3_PRIVATE_DATA_LENGTH ? WMV3_PRIVATE_DATA_LENGTH : get_codecpar(stream)->extradata_size); memcpy(PesPtr, privateData, WMV3_PRIVATE_DATA_LENGTH); PesPtr += WMV3_PRIVATE_DATA_LENGTH; /* Metadata Header Struct A */ - *PesPtr++ = (stream->codec->height >> 0) & 0xff; - *PesPtr++ = (stream->codec->height >> 8) & 0xff; - *PesPtr++ = (stream->codec->height >> 16) & 0xff; - *PesPtr++ = stream->codec->height >> 24; - *PesPtr++ = (stream->codec->width >> 0) & 0xff; - *PesPtr++ = (stream->codec->width >> 8) & 0xff; - *PesPtr++ = (stream->codec->width >> 16) & 0xff; - *PesPtr++ = stream->codec->width >> 24; + *PesPtr++ = (get_codecpar(stream)->height >> 0) & 0xff; + *PesPtr++ = (get_codecpar(stream)->height >> 8) & 0xff; + *PesPtr++ = (get_codecpar(stream)->height >> 16) & 0xff; + *PesPtr++ = get_codecpar(stream)->height >> 24; + *PesPtr++ = (get_codecpar(stream)->width >> 0) & 0xff; + *PesPtr++ = (get_codecpar(stream)->width >> 8) & 0xff; + *PesPtr++ = (get_codecpar(stream)->width >> 16) & 0xff; + *PesPtr++ = get_codecpar(stream)->width >> 24; PesPtr += 12; /* Skip flag word and Struct B first 8 bytes */ diff --git a/libspark/video.cpp b/libspark/video.cpp index dc9e443..11205b9 100644 --- a/libspark/video.cpp +++ b/libspark/video.cpp @@ -189,28 +189,46 @@ void write_frame(AVFrame* in_frame, FILE* fp) if (codec_context) { init_parameters(in_frame, codec_context); - if (avcodec_open2(codec_context, codec, 0) != -1){ + if (avcodec_open2(codec_context, codec, 0) != -1) { AVPacket pkt; av_init_packet(&pkt); /* encode the image */ +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57,37,100) int got_output = 0; int ret = avcodec_encode_video2(codec_context, &pkt, in_frame, &got_output); - if (ret != -1){ - if (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++){ + 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){ + if (ret != -1 && got_output) { fwrite(pkt.data, 1, pkt.size, fp); av_packet_unref(&pkt); } } } +#else + int ret = avcodec_send_frame(codec_context, in_frame); + if (!ret) { + /* signalling end of stream */ + ret = avcodec_send_frame(codec_context, NULL); + } + if (!ret) { + int i = 1; + /* get the delayed frames */ + in_frame->pts = i; + ret = avcodec_receive_packet(codec_context, &pkt); + if (!ret) { + fwrite(pkt.data, 1, pkt.size, fp); + av_packet_unref(&pkt); + } + } +#endif } avcodec_close(codec_context); av_free(codec_context); @@ -220,13 +238,29 @@ void write_frame(AVFrame* in_frame, FILE* fp) int decode_frame(AVCodecContext *codecContext,AVPacket &packet, FILE* fp) { - int decode_ok = 0; AVFrame *frame = av_frame_alloc(); if(frame){ +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57,37,100) + int decode_ok = 0; if ((avcodec_decode_video2(codecContext, frame, &decode_ok, &packet)) < 0 || !decode_ok){ av_frame_free(&frame); return -1; } +#else + int ret; + ret = avcodec_send_packet(codecContext, &packet); + // In particular, we don't expect AVERROR(EAGAIN), because we read all + // decoded frames with avcodec_receive_frame() until done. + if (ret < 0) { + av_frame_free(&frame); + return -1; + } + ret = avcodec_receive_frame(codecContext, frame); + if (ret < 0) { + av_frame_free(&frame); + return -1; + } +#endif AVFrame *dest_frame = av_frame_alloc(); if(dest_frame){ dest_frame->height = (frame->height/2)*2; @@ -250,11 +284,15 @@ 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); + AVCodec * codec = NULL; + AVCodecContext * codecContext = NULL; + int stream_index; +#if (LIBAVFORMAT_VERSION_INT < AV_VERSION_INT( 57,25,101 )) + stream_index = av_find_best_stream(formatContext, mediaType, -1, -1, NULL, 0); if (stream_index >=0 ){ - AVCodecContext * codecContext = formatContext->streams[stream_index]->codec; + codecContext = formatContext->streams[stream_index]->codec; if(codecContext){ - AVCodec *codec = avcodec_find_decoder(codecContext->codec_id); + codec = avcodec_find_decoder(codecContext->codec_id); if(codec){ if ((avcodec_open2(codecContext, codec, NULL)) != 0){ return NULL; @@ -264,13 +302,31 @@ AVCodecContext* open_codec(AVMediaType mediaType, AVFormatContext* formatContext } } return NULL; +#else + stream_index = av_find_best_stream(formatContext, mediaType, -1, -1, &codec, 0); + if (stream_index >= 0) { + codec = avcodec_find_decoder(formatContext->streams[stream_index]->codecpar->codec_id); + if (codec) { + codecContext = avcodec_alloc_context3(codec); + } + if (codecContext) { + if ((avcodec_open2(codecContext, codec, NULL)) != 0) { + return NULL; + } + return codecContext; + } + } + return NULL; +#endif } int image_to_mpeg2(const char *image_name, const char *encode_name) { int ret = 0; +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100) av_register_all(); avcodec_register_all(); +#endif AVFormatContext *formatContext = avformat_alloc_context(); if (formatContext && (ret = avformat_open_input(&formatContext, image_name, NULL, NULL)) == 0){ @@ -288,9 +344,12 @@ int image_to_mpeg2(const char *image_name, const char *encode_name) } fclose(fp); } - av_free_packet(&packet); + av_packet_unref(&packet); } avcodec_close(codecContext); +#if (LIBAVFORMAT_VERSION_INT > AV_VERSION_INT( 57,25,100 )) + avcodec_free_context(&codecContext); +#endif } avformat_close_input(&formatContext); }