Refactoring debug code

Conflicts:
	libeplayer3-arm/container/container_ffmpeg.c
This commit is contained in:
samsamsam
2019-01-11 18:57:06 +01:00
committed by Thilo Graf
parent 99844a02dd
commit f58a34e220
53 changed files with 1404 additions and 1398 deletions

View File

@@ -101,7 +101,7 @@ static void update_finish_timeout()
maxInjectedPts = 0;
}
//printf("ret[%d] playPts[%lld] currPts[%lld] maxInjectedPts[%lld]\n", ret, playPts, currPts, maxInjectedPts);
//printf("ret[%d] playPts[%" PRId64 "] currPts[%" PRId64 "] maxInjectedPts[%" PRId64 "]\n", ret, playPts, currPts, maxInjectedPts);
/* On some STBs PTS readed from decoder is invalid after seek or at start
* this is the reason for additional validation when we what to close immediately
@@ -596,7 +596,7 @@ static int64_t ffmpeg_seek(void *opaque __attribute__((unused)), int64_t offset,
if (diff > 0 && diff < rwdiff)
{
/* can do the seek inside the buffer */
ffmpeg_printf(20, "buffer-seek diff=%lld\n", diff);
ffmpeg_printf(20, "buffer-seek diff=%" PRId64 "\n", diff);
if (diff > (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_read)
{
ffmpeg_buf_read = ffmpeg_buf + (diff - ((ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_read));
@@ -609,7 +609,7 @@ static int64_t ffmpeg_seek(void *opaque __attribute__((unused)), int64_t offset,
else if (diff < 0 && diff * -1 < ffmpeg_buf_valid_size)
{
/* can do the seek inside the buffer */
ffmpeg_printf(20, "buffer-seek diff=%lld\n", diff);
ffmpeg_printf(20, "buffer-seek diff=%" PRId64 "\n", diff);
int32_t tmpdiff = diff * -1;
if (tmpdiff > ffmpeg_buf_read - ffmpeg_buf)
{
@@ -623,7 +623,7 @@ static int64_t ffmpeg_seek(void *opaque __attribute__((unused)), int64_t offset,
else
{
releasefillerMutex(__FILE__, __FUNCTION__, __LINE__);
ffmpeg_printf(20, "real-seek diff=%lld\n", diff);
ffmpeg_printf(20, "real-seek diff=%" PRId64 "\n", diff);
ffmpeg_do_seek_ret = 0;
ffmpeg_do_seek = diff;

View File

@@ -23,28 +23,7 @@
#include <stdint.h>
#include "common.h"
#ifdef SAM_WITH_DEBUG
#define CONTAINER_DEBUG
#else
#define CONTAINER_SILENT
#endif
#ifdef CONTAINER_DEBUG
static short debug_level = 0;
#define container_printf(level, x...) do { \
if (debug_level >= level) printf(x); } while (0)
#else
#define container_printf(level, x...)
#endif
#ifndef CONTAINER_SILENT
#define container_err(x...) do { printf(x); } while (0)
#else
#define container_err(x...)
#endif
#include "debug.h"
static Container_t *AvailableContainer[] =
{

View File

@@ -25,6 +25,7 @@
/* ***************************** */
/* Includes */
/* ***************************** */
#include "debug.h"
#include <stdio.h>
#include <stdlib.h>
@@ -66,30 +67,7 @@
* due to this we set own which use fopen/fread from
* std library.
*/
#define SAM_CUSTOM_IO
//#define SAM_WITH_DEBUG
#ifdef SAM_WITH_DEBUG
#define FFMPEG_DEBUG
#else
#define FFMPEG_SILENT
#endif
#ifdef FFMPEG_DEBUG
static short debug_level = 1;
#define ffmpeg_printf(level, fmt, x...) do { \
if (debug_level >= level) printf("[%s::%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
#else
#define ffmpeg_printf(level, fmt, x...)
#endif
#ifndef FFMPEG_SILENT
#define ffmpeg_err(fmt, x...) do { printf("[%s::%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0)
#else
#define ffmpeg_err(fmt, x...)
#endif
#define USE_CUSTOM_IO
/* Error Constants */
#define cERR_CONTAINER_FFMPEG_NO_ERROR 0
@@ -148,6 +126,7 @@ static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t ab
static int32_t container_ffmpeg_get_length(Context_t *context, int64_t *length);
static int64_t calcPts(uint32_t avContextIdx, AVStream *stream, int64_t pts);
static int32_t container_ffmpeg_stop(Context_t *context);
static int64_t doCalcPts(int64_t start_time, const AVRational time_base, int64_t pts);
/* Progressive playback means that we play local file
* but this local file can grows up, for example
@@ -321,7 +300,7 @@ int32_t ffmpeg_av_dict_set(const char *key, const char *value, int32_t flags)
static char *Codec2Encoding(int32_t codec_id, int32_t media_type, uint8_t *extradata, int extradata_size, int profile __attribute__((unused)), int32_t *version)
{
ffmpeg_printf(10, "Codec ID: %d (%.8lx)\n", codec_id, codec_id);
ffmpeg_printf(10, "Codec ID: %d (%.8x)\n", codec_id, codec_id);
switch (codec_id)
{
case AV_CODEC_ID_MPEG1VIDEO:
@@ -466,32 +445,27 @@ static char *Codec2Encoding(int32_t codec_id, int32_t media_type, uint8_t *extra
case AV_CODEC_ID_WEBVTT:
return "D_WEBVTT/SUBTITLES";
default:
ffmpeg_err("Codec ID %d (%.8lx) not found\n", codec_id, codec_id);
ffmpeg_err("Codec ID %d (%.8x) not found\n", codec_id, codec_id);
// Default to injected-pcm for unhandled audio types.
if (media_type == AVMEDIA_TYPE_AUDIO)
{
return "A_IPCM";
}
ffmpeg_err("Codec ID %d (%.8lx) not found\n", codec_id, codec_id);
ffmpeg_err("Codec ID %d (%.8x) not found\n", codec_id, codec_id);
}
return NULL;
}
static int64_t calcPts(uint32_t avContextIdx, AVStream *stream, int64_t pts)
static int64_t doCalcPts(int64_t start_time, const AVRational time_base, int64_t pts)
{
if (!stream || pts == (int64_t)AV_NOPTS_VALUE)
if (time_base.den > 0)
{
ffmpeg_err("stream / packet null\n");
return INVALID_PTS_VALUE;
}
else if (stream->time_base.den > 0)
{
pts = av_rescale(pts, (int64_t)stream->time_base.num * 90000, stream->time_base.den);
pts = av_rescale(pts, (int64_t)time_base.num * 90000, time_base.den);
}
if (avContextTab[avContextIdx]->start_time != AV_NOPTS_VALUE)
if (start_time != AV_NOPTS_VALUE)
{
pts -= 90000 * avContextTab[avContextIdx]->start_time / AV_TIME_BASE;
pts -= 90000 * start_time / AV_TIME_BASE;
}
if (pts & 0x8000000000000000ull)
@@ -506,6 +480,17 @@ static int64_t calcPts(uint32_t avContextIdx, AVStream *stream, int64_t pts)
return pts;
}
static int64_t calcPts(uint32_t avContextIdx, AVStream *stream, int64_t pts)
{
if (!stream || pts == (int64_t)AV_NOPTS_VALUE)
{
ffmpeg_err("stream / packet null\n");
return INVALID_PTS_VALUE;
}
return doCalcPts(avContextTab[avContextIdx]->start_time, stream->time_base, pts);
}
/* search for metatdata in context and stream
* and map it to our metadata.
*/
@@ -576,9 +561,7 @@ static void FFMPEGThread(Context_t *context)
uint32_t cAVIdx = 0;
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 100)
Mpeg4P2Context mpeg4p2_context;
memset(&mpeg4p2_context, 0, sizeof(Mpeg4P2Context));
AVBitStreamFilterContext *mpeg4p2_bsf_context = av_bitstream_filter_init("mpeg4_unpack_bframes");
Mpeg4P2Context *mpeg4p2_context = mpeg4p2_context_open();
#endif
#ifdef HAVE_FLV2MPEG4_CONVERTER
Flv2Mpeg4Context flv2mpeg4_context;
@@ -691,7 +674,7 @@ static void FFMPEGThread(Context_t *context)
isWaitingForFinish = 0;
if (do_seek_target_seconds)
{
ffmpeg_printf(10, "seek_target_seconds[%lld]\n", seek_target_seconds);
ffmpeg_printf(10, "seek_target_seconds[%" PRId64 "]\n", seek_target_seconds);
uint32_t i = 0;
for (; i < IPTV_AV_CONTEXT_MAX_NUM; i += 1)
{
@@ -746,12 +729,7 @@ static void FFMPEGThread(Context_t *context)
}
}
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 100)
mpeg4p2_context_reset(&mpeg4p2_context);
if (NULL != mpeg4p2_bsf_context)
{
av_bitstream_filter_close(mpeg4p2_bsf_context);
mpeg4p2_bsf_context = av_bitstream_filter_init("mpeg4_unpack_bframes");
}
mpeg4p2_context_reset(mpeg4p2_context);
#endif
#ifdef HAVE_FLV2MPEG4_CONVERTER
flv2mpeg4_context_reset(&flv2mpeg4_context);
@@ -810,7 +788,7 @@ static void FFMPEGThread(Context_t *context)
}
else
{
ffmpeg_printf(1, "SKIP DISCARDED PACKET stream_index[%d] pid[%d]\n", packet.size, (int)packet.stream_index, pid);
ffmpeg_printf(1, "SKIP DISCARDED PACKET packed_size[%d] stream_index[%d] pid[%d]\n", packet.size, (int)packet.stream_index, pid);
}
ffmpeg_printf(200, "packet.size %d - index %d\n", packet.size, pid);
@@ -819,19 +797,9 @@ static void FFMPEGThread(Context_t *context)
{
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 100)
AVCodecContext *codec_context = videoTrack->avCodecCtx;
if (codec_context && codec_context->codec_id == AV_CODEC_ID_MPEG4 && NULL != mpeg4p2_bsf_context)
if (codec_context && codec_context->codec_id == AV_CODEC_ID_MPEG4 && NULL != mpeg4p2_context)
{
// should never happen, if it does print error and exit immediately, so we can easily spot it
if (filter_packet(mpeg4p2_bsf_context, codec_context, &packet) < 0)
{
ffmpeg_err("cannot filter mpegp2 packet\n");
exit(1);
}
if (mpeg4p2_write_packet(context, &mpeg4p2_context, videoTrack, cAVIdx, &currentVideoPts, &latestPts, &packet) < 0)
{
ffmpeg_err("cannot write mpeg4p2 packet\n");
exit(1);
}
mpeg4p2_write_packet(context, mpeg4p2_context, videoTrack, cAVIdx, &currentVideoPts, &latestPts, &packet);
update_max_injected_pts(latestPts);
}
else
@@ -886,7 +854,7 @@ static void FFMPEGThread(Context_t *context)
continue;
}
ffmpeg_printf(200, "VideoTrack index = %d %lld\n", pid, currentVideoPts);
ffmpeg_printf(200, "VideoTrack index = %d %" PRId64 "\n", pid, currentVideoPts);
avOut.data = packet.data;
avOut.len = packet.size;
@@ -1143,7 +1111,7 @@ static void FFMPEGThread(Context_t *context)
ffmpeg_err("av_samples_alloc: %d\n", -e);
continue;
}
int64_t next_in_pts = av_rescale(av_frame_get_best_effort_timestamp(decoded_frame),
int64_t next_in_pts = av_rescale(wrapped_frame_get_best_effort_timestamp(decoded_frame),
((AVStream *) audioTrack->stream)->time_base.num * (int64_t)out_sample_rate * c->sample_rate,
((AVStream *) audioTrack->stream)->time_base.den);
int64_t next_out_pts = av_rescale(swr_next_pts(swr, next_in_pts),
@@ -1189,7 +1157,7 @@ static void FFMPEGThread(Context_t *context)
else if (audioTrack->have_aacheader == 1)
{
ffmpeg_printf(200, "write audio aac\n");
ffmpeg_printf(200, ">>>>>>> %x %x %x %x %x %x %x\n", packet.data[0], packet.data[1], packet.data[2], packet.data[3], packet.data[4], packet.data[5], packet.data[6]);
ffmpeg_printf(200, "> %hhx %hhx %hhx %hhx %x %hhx %hhx\n", packet.data[0], packet.data[1], packet.data[2], packet.data[3], packet.data[4], packet.data[5], packet.data[6]);
avOut.data = packet.data;
avOut.len = packet.size;
@@ -1349,11 +1317,7 @@ static void FFMPEGThread(Context_t *context)
}
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 100)
mpeg4p2_context_reset(&mpeg4p2_context);
if (NULL != mpeg4p2_bsf_context)
{
av_bitstream_filter_close(mpeg4p2_bsf_context);
}
mpeg4p2_context_close(mpeg4p2_context);
#endif
hasPlayThreadStarted = 0;
@@ -1381,7 +1345,7 @@ static int32_t interrupt_cb(void *ctx)
return p->abortRequested || PlaybackDieNow(0);
}
#ifdef SAM_CUSTOM_IO
#ifdef USE_CUSTOM_IO
typedef struct CustomIOCtx_t
{
FILE *pFile;
@@ -1543,7 +1507,7 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, uin
avContextTab[AVIdx]->interrupt_callback.callback = interrupt_cb;
avContextTab[AVIdx]->interrupt_callback.opaque = context->playback;
#ifdef SAM_CUSTOM_IO
#ifdef USE_CUSTOM_IO
if (0 == strstr(filename, "://") ||
0 == strncmp(filename, "file://", 7))
{
@@ -1917,15 +1881,14 @@ int32_t container_ffmpeg_init(Context_t *context, PlayFiles_t *playFilesNames)
}
/* initialize ffmpeg */
avcodec_register_all();
av_register_all();
wrapped_register_all();
avformat_network_init();
// SULGE DEBUG ENABLED
// make ffmpeg silen
// av_log_set_level(AV_LOG_DEBUG);
#if FFMPEG_DEBUG_LEVEL >= 10
av_log_set_level(AV_LOG_DEBUG);
#else
av_log_set_callback(ffmpeg_silen_callback);
#endif
context->playback->abortRequested = 0;
int32_t res = container_ffmpeg_init_av_context(context, playFilesNames->szFirstFile, playFilesNames->iFirstFileSize, \
@@ -2156,7 +2119,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32
track.TimeScale = 1000;
}
ffmpeg_printf(10, "bit_rate [%lld]\n", get_codecpar(stream)->bit_rate);
ffmpeg_printf(10, "bit_rate [%" PRId64 "]\n", get_codecpar(stream)->bit_rate);
ffmpeg_printf(10, "time_base.den [%d]\n", stream->time_base.den);
ffmpeg_printf(10, "time_base.num [%d]\n", stream->time_base.num);
ffmpeg_printf(10, "width [%d]\n", get_codecpar(stream)->width);
@@ -2187,7 +2150,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32
{
track.avCodecCtx = wrapped_avcodec_get_context(cAVIdx, stream);
}
ffmpeg_printf(1, "cAVIdx[%d]: MANAGER_ADD track VIDEO\n");
ffmpeg_printf(1, "cAVIdx[%d]: MANAGER_ADD track VIDEO\n", cAVIdx);
if (context->manager->video->Command(context, MANAGER_ADD, &track) < 0)
{
/* konfetti: fixme: is this a reason to return with error? */
@@ -2515,7 +2478,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32
if (context->manager->audio)
{
ffmpeg_printf(1, "cAVIdx[%d]: MANAGER_ADD track AUDIO\n");
ffmpeg_printf(1, "cAVIdx[%d]: MANAGER_ADD track AUDIO\n", cAVIdx);
if (context->manager->audio->Command(context, MANAGER_ADD, &track) < 0)
{
if(track.aacbuf){
@@ -2780,7 +2743,7 @@ static int32_t container_ffmpeg_seek_bytes(off_t pos)
int32_t flag = AVSEEK_FLAG_BYTE;
off_t current_pos = avio_tell(avContextTab[0]->pb);
ffmpeg_printf(20, "seeking to position %lld (bytes)\n", pos);
ffmpeg_printf(20, "seeking to position %" PRId64 " (bytes)\n", pos);
if (current_pos > pos)
{
@@ -2793,7 +2756,7 @@ static int32_t container_ffmpeg_seek_bytes(off_t pos)
return cERR_CONTAINER_FFMPEG_ERR;
}
ffmpeg_printf(30, "current_pos after seek %lld\n", avio_tell(avContextTab[0]->pb));
ffmpeg_printf(30, "current_pos after seek %" PRId64 "\n", avio_tell(avContextTab[0]->pb));
return cERR_CONTAINER_FFMPEG_NO_ERROR;
}
@@ -2807,7 +2770,7 @@ static int32_t container_ffmpeg_seek_rel(Context_t *context, off_t pos, int64_t
Track_t *current = NULL;
seek_target_flag = 0;
ffmpeg_printf(10, "seeking %f sec relativ to %lld\n", sec, pos);
ffmpeg_printf(10, "seeking %" PRId64 " sec relativ to %" PRId64 "\n", sec, pos);
context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack);
context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack);
@@ -2865,7 +2828,7 @@ static int32_t container_ffmpeg_seek_rel(Context_t *context, off_t pos, int64_t
return cERR_CONTAINER_FFMPEG_END_OF_FILE;
}
ffmpeg_printf(10, "1. seeking to position %lld bytes ->sec %f\n", pos, sec);
ffmpeg_printf(10, "1. seeking to position %" PRId64 " bytes ->sec %f\n", pos, sec);
seek_target_bytes = pos;
do_seek_target_bytes = 1;
@@ -2882,7 +2845,7 @@ static int32_t container_ffmpeg_seek_rel(Context_t *context, off_t pos, int64_t
sec = 0;
}
ffmpeg_printf(10, "2. seeking to position %f sec ->time base %f %d\n", sec, av_q2d(((AVStream *) current->stream)->time_base), AV_TIME_BASE);
ffmpeg_printf(10, "2. seeking to position %" PRId64 " sec ->time base %f %d\n", sec, av_q2d(((AVStream *) current->stream)->time_base), AV_TIME_BASE);
seek_target_seconds = sec * AV_TIME_BASE;
do_seek_target_seconds = 1;
@@ -2904,7 +2867,7 @@ static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t ab
if (!absolute)
{
ffmpeg_printf(10, "seeking %lld sec\n", sec / AV_TIME_BASE);
ffmpeg_printf(10, "seeking %" PRId64 " sec\n", sec / AV_TIME_BASE);
if (sec == 0)
{
ffmpeg_err("sec = 0 ignoring\n");
@@ -2928,7 +2891,7 @@ static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t ab
}
}
ffmpeg_printf(10, "goto %lld sec\n", sec / AV_TIME_BASE);
ffmpeg_printf(10, "goto %" PRId64 " sec\n", sec / AV_TIME_BASE);
context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack);
context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack);
@@ -2982,7 +2945,7 @@ static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t ab
off_t pos = avio_tell(avContextTab[0]->pb);
releaseMutex(__FILE__, __FUNCTION__, __LINE__);
ffmpeg_printf(10, "pos %lld %lld\n", pos, avContextTab[0]->bit_rate);
ffmpeg_printf(10, "pos %" PRId64 " %lld\n", pos, avContextTab[0]->bit_rate);
if (avContextTab[0]->bit_rate)
{
@@ -3001,7 +2964,7 @@ static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t ab
pos = 0;
}
ffmpeg_printf(10, "1. seeking to position %lld bytes ->sec %lld\n", pos / AV_TIME_BASE, sec / AV_TIME_BASE);
ffmpeg_printf(10, "1. seeking to position %" PRId64 " bytes ->sec %lld\n", pos / AV_TIME_BASE, sec / AV_TIME_BASE);
seek_target_bytes = pos / AV_TIME_BASE;
do_seek_target_bytes = 1;

269
libeplayer3-arm/container/mpeg4p2_ffmpeg.c Normal file → Executable file
View File

@@ -3,108 +3,46 @@
// http://forums.openpli.org/topic/39326-gstreamer10-and-mpeg4-part2/?hl=%2Bmpeg4+%2Bpart2
//
#define MPEG4P2_MAX_B_FRAMES_COUNT 5
// mpeg4_unpack_bframes
typedef struct
{
int b_frames_count;
int first_ip_frame_written;
int64_t packet_duration;
AVPacket *b_frames[MPEG4P2_MAX_B_FRAMES_COUNT];
AVPacket *second_ip_frame;
const AVBitStreamFilter *bsf;
AVBSFContext *ctx;
} Mpeg4P2Context;
static void set_packet(AVPacket **pkt_dest, AVPacket *pkt_src)
static Mpeg4P2Context *mpeg4p2_context_open()
{
if (pkt_dest == NULL)
return;
if (*pkt_dest != NULL)
Mpeg4P2Context *context = NULL;
const AVBitStreamFilter *bsf = av_bsf_get_by_name("mpeg4_unpack_bframes");
if (bsf)
{
wrapped_packet_unref(*pkt_dest);
av_free(*pkt_dest);
}
*pkt_dest = av_malloc(sizeof(AVPacket));
av_packet_ref(*pkt_dest, pkt_src);
}
static int filter_packet(AVBitStreamFilterContext *bsf_ctx, AVCodecContext *enc_ctx, AVPacket *pkt)
{
int ret;
AVPacket new_pkt = *pkt;
ret = av_bitstream_filter_filter(bsf_ctx, enc_ctx, NULL,
&new_pkt.data, &new_pkt.size,
pkt->data, pkt->size,
pkt->flags & AV_PKT_FLAG_KEY);
if (ret == 0 && new_pkt.data != pkt->data)
{
if ((ret = av_packet_ref(&new_pkt, pkt)) < 0)
return -1;
ret = 1;
}
if (ret > 0)
{
pkt->side_data = NULL;
pkt->side_data_elems = 0;
wrapped_packet_unref(pkt);
new_pkt.buf = av_buffer_create(new_pkt.data, new_pkt.size,
av_buffer_default_free, NULL, 0);
if (!new_pkt.buf)
return -1;
}
if (ret < 0)
{
ffmpeg_err("Failed to filter bitstream with filter %s for stream %d with codec %s\n",
bsf_ctx->filter->name, pkt->stream_index,
avcodec_get_name(enc_ctx->codec_id));
return -1;
}
*pkt = new_pkt;
return 0;
}
static void mpeg4p2_context_reset(Mpeg4P2Context *context)
{
if (context == NULL)
return;
int i;
for (i = 0; i < MPEG4P2_MAX_B_FRAMES_COUNT; i++)
{
if (context->b_frames[i] != NULL)
context = malloc(sizeof(Mpeg4P2Context));
if (context)
{
wrapped_packet_unref(context->b_frames[i]);
av_free(context->b_frames[i]);
memset(context, 0x00, sizeof(Mpeg4P2Context));
context->bsf = bsf;
}
context->b_frames[i] = NULL;
}
if (context->second_ip_frame != NULL)
{
wrapped_packet_unref(context->second_ip_frame);
av_free(context->second_ip_frame);
}
context->second_ip_frame = NULL;
context->b_frames_count = 0;
context->first_ip_frame_written = 0;
context->packet_duration = 0;
return context;
}
static void mpeg4p2_write(Context_t *ctx, Track_t *track, int avContextIdx, int64_t *pts_current, int64_t *pts_latest, AVPacket *pkt)
static void mpeg4p2_write(Context_t *ctx, Mpeg4P2Context *mpeg4p2_ctx, Track_t *track, int64_t start_time, int64_t *currentVideoPts, int64_t *latestPts, AVPacket *pkt)
{
*pts_current = track->pts = calcPts(avContextIdx, track->stream, pkt->pts);
if ((*pts_current > *pts_latest) && (*pts_current != INVALID_PTS_VALUE))
*currentVideoPts = track->pts = doCalcPts(start_time, mpeg4p2_ctx->ctx->time_base_out, pkt->pts);
if ((*currentVideoPts > *latestPts) && (*currentVideoPts != INVALID_PTS_VALUE))
{
*pts_latest = *pts_current;
*latestPts = *currentVideoPts;
}
track->dts = calcPts(avContextIdx, track->stream, pkt->dts);
track->dts = doCalcPts(start_time, mpeg4p2_ctx->ctx->time_base_out, pkt->dts);
AudioVideoOut_t avOut;
avOut.data = pkt->data;
avOut.len = pkt->size;
avOut.pts = track->pts;
avOut.dts = track->dts;
avOut.extradata = track->extraData;
avOut.extralen = track->extraSize;
avOut.extradata = mpeg4p2_ctx->ctx->par_out->extradata;
avOut.extralen = mpeg4p2_ctx->ctx->par_out->extradata_size;
avOut.frameRate = track->frame_rate;
avOut.timeScale = track->TimeScale;
avOut.width = track->width;
@@ -117,97 +55,90 @@ static void mpeg4p2_write(Context_t *ctx, Track_t *track, int avContextIdx, int6
}
}
static int mpeg4p2_write_packet(Context_t *ctx, Mpeg4P2Context *mpeg4p2_ctx, Track_t *track, int cAVIdx, int64_t *pts_current, int64_t *pts_latest, AVPacket *pkt)
static int mpeg4p2_context_reset(Mpeg4P2Context *context)
{
uint8_t *data = pkt->data;
int data_len = pkt->size;
int pos = 0;
if (mpeg4p2_ctx->packet_duration == 0)
int ret = 0;
if (context && context->ctx)
{
mpeg4p2_ctx->packet_duration = pkt->duration;
}
while (pos < data_len)
{
if (memcmp(&data[pos], "\x00\x00\x01\xb6", 4))
// Flush
ret = av_bsf_send_packet(context->ctx, NULL);
if (ret == 0)
{
pos++;
continue;
}
pos += 4;
switch ((data[pos] & 0xC0) >> 6)
{
case 0: // I-Frame
case 1: // P-Frame
if (!mpeg4p2_ctx->first_ip_frame_written)
{
mpeg4p2_ctx->first_ip_frame_written = 1;
pkt->pts = pkt->dts + mpeg4p2_ctx->packet_duration;
ffmpeg_printf(100, "Writing first I/P packet\n");
mpeg4p2_write(ctx, track, cAVIdx, pts_current, pts_latest, pkt);
return 0;
}
else if (!mpeg4p2_ctx->second_ip_frame)
{
set_packet(&mpeg4p2_ctx->second_ip_frame, pkt);
return 0;
}
else
{
if (!mpeg4p2_ctx->b_frames_count)
{
mpeg4p2_ctx->second_ip_frame->pts = mpeg4p2_ctx->second_ip_frame->dts + mpeg4p2_ctx->packet_duration;
ffmpeg_printf(100, "Writing second I/P packet(1)\n");
mpeg4p2_write(ctx, track, cAVIdx, pts_current, pts_latest, mpeg4p2_ctx->second_ip_frame);
set_packet(&mpeg4p2_ctx->second_ip_frame, pkt);
return 0;
}
else
{
mpeg4p2_ctx->second_ip_frame->pts = mpeg4p2_ctx->b_frames[mpeg4p2_ctx->b_frames_count - 1]->dts + mpeg4p2_ctx->packet_duration;
mpeg4p2_ctx->b_frames[0]->pts = mpeg4p2_ctx->second_ip_frame->dts + mpeg4p2_ctx->packet_duration;
int i;
for (i = 1; i < mpeg4p2_ctx->b_frames_count; i++)
{
mpeg4p2_ctx->b_frames[i]->pts = mpeg4p2_ctx->b_frames[i - 1]->dts + mpeg4p2_ctx->packet_duration;
}
ffmpeg_printf(100, "Writing second I/P packet(2)\n");
mpeg4p2_write(ctx, track, cAVIdx, pts_current, pts_latest, mpeg4p2_ctx->second_ip_frame);
set_packet(&mpeg4p2_ctx->second_ip_frame, pkt);
for (i = 0; i < mpeg4p2_ctx->b_frames_count; i++)
{
ffmpeg_printf(100, "Writing B-frame[%d]\n", i);
mpeg4p2_write(ctx, track, cAVIdx, pts_current, pts_latest, mpeg4p2_ctx->b_frames[i]);
}
mpeg4p2_ctx->b_frames_count = 0;
return 0;
}
}
break;
case 3: // S-Frame
break;
case 2: // B-Frame
if (!mpeg4p2_ctx->second_ip_frame)
{
ffmpeg_err("Cannot predict B-Frame without surrounding I/P-Frames, dropping...");
return 0;
}
if (mpeg4p2_ctx->b_frames_count == MPEG4P2_MAX_B_FRAMES_COUNT)
{
ffmpeg_err("Oops max B-Frames count = %d, reached", MPEG4P2_MAX_B_FRAMES_COUNT);
// not recoverable, to fix just increase MPEG4P2_MAX_B_FRAMES_COUNT
return -1;
}
else
{
ffmpeg_printf(100, "Storing B-Frame\n");
set_packet(&mpeg4p2_ctx->b_frames[mpeg4p2_ctx->b_frames_count++], pkt);
return 0;
}
case 4:
default:
break;
AVPacket *pkt = NULL;
while ((ret = av_bsf_receive_packet(context->ctx, pkt)) == 0)
{
wrapped_frame_unref(pkt);
}
}
av_bsf_free(&context->ctx);
}
return ret;
}
static int mpeg4p2_write_packet(Context_t *ctx, Mpeg4P2Context *mpeg4p2_ctx, Track_t *track, int cAVIdx, int64_t *pts_current, int64_t *pts_latest, AVPacket *pkt)
{
int ret = 0;
if (mpeg4p2_ctx)
{
// Setup is needed
if (!mpeg4p2_ctx->ctx)
{
ret = av_bsf_alloc(mpeg4p2_ctx->bsf, &mpeg4p2_ctx->ctx);
if (ret == 0)
{
AVStream *in = track->stream;
ret = avcodec_parameters_copy(mpeg4p2_ctx->ctx->par_in, in->codecpar);
if (ret == 0)
{
mpeg4p2_ctx->ctx->time_base_in = in->time_base;
ret = av_bsf_init(mpeg4p2_ctx->ctx);
}
}
}
if (ret == 0)
{
ret = av_bsf_send_packet(mpeg4p2_ctx->ctx, pkt);
if (ret == 0)
{
while ((ret = av_bsf_receive_packet(mpeg4p2_ctx->ctx, pkt)) == 0)
{
mpeg4p2_write(ctx, mpeg4p2_ctx, track, avContextTab[cAVIdx]->start_time, pts_current, pts_latest, pkt);
}
if (ret == AVERROR(EAGAIN))
{
return 0;
}
if (ret < 0)
{
ffmpeg_err("av_bsf_receive_packet failed error 0x%x\n", ret);
mpeg4p2_context_reset(mpeg4p2_ctx);
}
}
}
else
{
ffmpeg_err("bsf setup failed error 0x%x\n", ret);
}
}
else
{
ret = -1;
}
return ret;
}
static void mpeg4p2_context_close(Mpeg4P2Context *context)
{
if (context)
{
mpeg4p2_context_reset(context);
free(context);
return;
}
return 0;
}

View File

@@ -153,8 +153,11 @@ static AVCodecContext *wrapped_avcodec_get_context(uint32_t cAVIdx, AVStream *st
avcodec_free_context(&avCodecCtx);
return NULL;
}
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100)
av_codec_set_pkt_timebase(avCodecCtx, stream->time_base);
#else
avCodecCtx->pkt_timebase = stream->time_base;
#endif
store_avcodec_context(avCodecCtx, cAVIdx, stream->id);
}
@@ -187,3 +190,22 @@ static void wrapped_avcodec_flush_buffers(uint32_t cAVIdx)
}
#endif
}
static void wrapped_register_all(void)
{
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100)
avcodec_register_all();
av_register_all();
#endif
}
static int64_t wrapped_frame_get_best_effort_timestamp(const AVFrame *frame)
{
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100)
return av_frame_get_best_effort_timestamp(frame);
#else
return frame->best_effort_timestamp;
#endif
}