libeplayer3: cleanup

This commit is contained in:
martii
2013-07-14 10:04:05 +02:00
committed by Stefan Seyfried
parent 8affebdef6
commit b9c8d61b3a
3 changed files with 70 additions and 352 deletions

View File

@@ -113,16 +113,19 @@ static unsigned char isContainerRunning = 0;
long long int latestPts = 0; long long int latestPts = 0;
static int restart_audio_resampling = 0;
static off_t seek_target_bytes = 0;
static int do_seek_target_bytes = 0;
static float seek_target_seconds = 0.0;
static int do_seek_target_seconds = 0;
static int seek_target_flag = 0;
/* ***************************** */ /* ***************************** */
/* Prototypes */ /* Prototypes */
/* ***************************** */ /* ***************************** */
static int container_ffmpeg_seek_bytes(off_t pos); static int container_ffmpeg_seek_bytes(off_t pos);
static int container_ffmpeg_seek(Context_t *context, float sec, int absolute); static int container_ffmpeg_seek(Context_t *context, float sec, int absolute);
static int container_ffmpeg_seek_rel(Context_t *context, off_t pos, long long int pts, float sec); static int container_ffmpeg_seek_rel(Context_t *context, off_t pos, long long int pts, float sec);
#define use_sec_to_seek
#if !defined(use_sec_to_seek)
static int container_ffmpeg_seek_bytes_rel(off_t start, off_t bytes);
#endif
/* ***************************** */ /* ***************************** */
/* MISC Functions */ /* MISC Functions */
@@ -256,7 +259,7 @@ long long int calcPts(AVStream* stream, AVPacket* packet)
else if (avContext->start_time == AV_NOPTS_VALUE) else if (avContext->start_time == AV_NOPTS_VALUE)
pts = 90000.0 * (double)packet->pts * av_q2d(stream->time_base); pts = 90000.0 * (double)packet->pts * av_q2d(stream->time_base);
else else
pts = 90000.0 * (((double)(packet->pts) * av_q2d(stream->time_base)) - (avContext->start_time / AV_TIME_BASE)); pts = 90000.0 * (double)packet->pts * av_q2d(stream->time_base) - 90000.0 * avContext->start_time / AV_TIME_BASE;
if (pts & 0x8000000000000000ull) if (pts & 0x8000000000000000ull)
pts = INVALID_PTS_VALUE; pts = INVALID_PTS_VALUE;
@@ -331,11 +334,7 @@ static void FFMPEGThread(Context_t *context) {
AVPacket packet; AVPacket packet;
off_t lastSeek = -1; off_t lastSeek = -1;
long long int lastPts = -1, currentVideoPts = -1, currentAudioPts = -1, showtime = 0, bofcount = 0; long long int lastPts = -1, currentVideoPts = -1, currentAudioPts = -1, showtime = 0, bofcount = 0;
int err = 0, audioMute = 0; int err = 0;
#ifdef reverse_playback_2
int gotlastPts = 0;
off_t lastReverseSeek = 0; /* max address to read before seek again in reverse play */
#endif
AudioVideoOut_t avOut; AudioVideoOut_t avOut;
#ifdef USE_LIBSWRESAMPLE #ifdef USE_LIBSWRESAMPLE
@@ -373,11 +372,8 @@ static void FFMPEGThread(Context_t *context) {
continue; continue;
} }
#define reverse_playback_3
#ifdef reverse_playback_3
if (context->playback->BackWard && av_gettime() >= showtime) if (context->playback->BackWard && av_gettime() >= showtime)
{ {
audioMute = 1;
context->output->Command(context, OUTPUT_CLEAR, "video"); context->output->Command(context, OUTPUT_CLEAR, "video");
if(bofcount == 1) if(bofcount == 1)
@@ -395,8 +391,7 @@ static void FFMPEGThread(Context_t *context) {
lastPts = currentAudioPts; lastPts = currentAudioPts;
} }
if((err = container_ffmpeg_seek_rel(context, lastSeek, lastPts, (float) context->playback->Speed)) < 0)
if((err = container_ffmpeg_seek_rel(context, lastSeek, lastPts, (float) context->playback->Speed * 15)) < 0)
{ {
ffmpeg_err( "Error seeking\n"); ffmpeg_err( "Error seeking\n");
@@ -406,80 +401,27 @@ static void FFMPEGThread(Context_t *context) {
} }
} }
}
if (do_seek_target_seconds || do_seek_target_bytes) {
if (do_seek_target_seconds) {
float seek_target_seconds_min = seek_target_seconds - 15 * AV_TIME_BASE;
avformat_seek_file(avContext, -1, seek_target_seconds_min, seek_target_seconds, INT64_MAX, seek_target_flag);
} else
container_ffmpeg_seek_bytes(seek_target_bytes);
do_seek_target_seconds = do_seek_target_bytes = 0;
restart_audio_resampling = 1;
latestPts = 0;
seek_target_flag = 0;
}
if (context->playback->BackWard) {
lastPts = lastPts + (context->playback->Speed * 90000); lastPts = lastPts + (context->playback->Speed * 90000);
showtime = av_gettime() + 300000; //jump back all 300ms showtime = av_gettime() + 300000; //jump back all 300ms
}
if(!context->playback->BackWard && audioMute)
{
lastPts = -1;
bofcount = 0;
showtime = 0;
audioMute = 0;
context->output->Command(context, OUTPUT_AUDIOMUTE, "0"); context->output->Command(context, OUTPUT_AUDIOMUTE, "0");
} }
#endif
#ifdef reverse_playback_2
/* should we seek back again ?
* reverse play and currentReadPosition >= end of seek reverse play area ? */
if ((context->playback->BackWard) && (currentReadPosition >= lastReverseSeek))
{
/* fixme: surplus detection */
int surplus = 1;
ffmpeg_printf(20, "new seek ->c %lld, l %lld, ls %lld, lp %lld\n", currentReadPosition, lastReverseSeek, lastSeek, lastPts);
context->output->Command(context, OUTPUT_DISCONTINUITY_REVERSE, &surplus);
/* save the maximum read position, if we reach this, we must
* seek back again.
*/
if(lastReverseSeek == 0)
lastReverseSeek = currentReadPosition;
else
lastReverseSeek = lastSeek;
#if defined(use_sec_to_seek)
if ((err = container_ffmpeg_seek_rel(context, lastSeek, lastPts, -5)) < 0)
#else
if ((err = container_ffmpeg_seek_bytes_rel(lastSeek, /* context->playback->BackWard */ -188 * 200)) < 0)
#endif
{
ffmpeg_err( "Error seeking\n");
if (err == cERR_CONTAINER_FFMPEG_END_OF_FILE)
{
break;
}
}
else
{
lastSeek = currentReadPosition = avio_tell(avContext->pb);
gotlastPts = 1;
#ifndef use_sec_to_seek
if (err != lastSeek)
ffmpeg_err("upssssssssssssssss seek not doing what I want\n");
#endif
/*
if (currentVideoPts != -1)
lastPts = currentVideoPts;
else
lastPts = currentAudioPts;
*/
}
} else
if (!context->playback->BackWard)
{
lastReverseSeek = 0;
lastSeek = -1;
lastPts = -1;
gotlastPts = 0;
}
#endif
getMutex(FILENAME, __FUNCTION__,__LINE__); getMutex(FILENAME, __FUNCTION__,__LINE__);
if (av_read_frame(avContext, &packet) == 0 ) if (av_read_frame(avContext, &packet) == 0 )
@@ -519,14 +461,6 @@ static void FFMPEGThread(Context_t *context) {
if ((currentVideoPts > latestPts) && (currentVideoPts != INVALID_PTS_VALUE)) if ((currentVideoPts > latestPts) && (currentVideoPts != INVALID_PTS_VALUE))
latestPts = currentVideoPts; latestPts = currentVideoPts;
#ifdef reverse_playback_2
if (currentVideoPts != INVALID_PTS_VALUE && gotlastPts == 1)
{
lastPts = currentVideoPts;
gotlastPts = 0;
}
#endif
ffmpeg_printf(200, "VideoTrack index = %d %lld\n",pid, currentVideoPts); ffmpeg_printf(200, "VideoTrack index = %d %lld\n",pid, currentVideoPts);
avOut.data = packet.data; avOut.data = packet.data;
@@ -553,14 +487,6 @@ static void FFMPEGThread(Context_t *context) {
if ((currentAudioPts > latestPts) && (!videoTrack)) if ((currentAudioPts > latestPts) && (!videoTrack))
latestPts = currentAudioPts; latestPts = currentAudioPts;
#ifdef reverse_playback_2
if (currentAudioPts != INVALID_PTS_VALUE && gotlastPts == 1 && (!videoTrack))
{
lastPts = currentAudioPts;
gotlastPts = 0;
}
#endif
ffmpeg_printf(200, "AudioTrack index = %d\n",pid); ffmpeg_printf(200, "AudioTrack index = %d\n",pid);
if (audioTrack->inject_raw_pcm == 1){ if (audioTrack->inject_raw_pcm == 1){
ffmpeg_printf(200,"write audio raw pcm\n"); ffmpeg_printf(200,"write audio raw pcm\n");
@@ -582,10 +508,7 @@ static void FFMPEGThread(Context_t *context) {
avOut.height = 0; avOut.height = 0;
avOut.type = "audio"; avOut.type = "audio";
#ifdef reverse_playback_3 if (!context->playback->BackWard && context->output->audio->Write(context, &avOut) < 0)
if (!context->playback->BackWard)
#endif
if (context->output->audio->Write(context, &avOut) < 0)
{ {
ffmpeg_err("(raw pcm) writing data to audio device failed\n"); ffmpeg_err("(raw pcm) writing data to audio device failed\n");
} }
@@ -596,6 +519,34 @@ static void FFMPEGThread(Context_t *context) {
AVCodecContext *c = ((AVStream*)(audioTrack->stream))->codec; AVCodecContext *c = ((AVStream*)(audioTrack->stream))->codec;
AVPacket avpkt = packet; AVPacket avpkt = packet;
if (restart_audio_resampling) {
restart_audio_resampling = 0;
// flush streams
unsigned int i;
for (i = 0; i < avContext->nb_streams; i++)
if (avContext->streams[i]->codec && avContext->streams[i]->codec->codec)
avcodec_flush_buffers(avContext->streams[i]->codec);
#ifdef USE_LIBSWRESAMPLE
if (swr) {
swr_free(&swr);
swr = NULL;
}
#else
if (avr) {
avresample_close(avr);
avresample_free(&avr);
avr = NULL;
}
#endif
if (decoded_frame) {
avcodec_free_frame(&decoded_frame);
decoded_frame = NULL;
}
context->output->Command(context, OUTPUT_FLUSH, NULL);
context->output->Command(context, OUTPUT_PLAY, NULL);
}
while(avpkt.size > 0) while(avpkt.size > 0)
{ {
@@ -725,10 +676,7 @@ static void FFMPEGThread(Context_t *context) {
avOut.height = 0; avOut.height = 0;
avOut.type = "audio"; avOut.type = "audio";
#ifdef reverse_playback_3 if (!context->playback->BackWard && context->output->audio->Write(context, &avOut) < 0)
if (!context->playback->BackWard)
#endif
if (context->output->audio->Write(context, &avOut) < 0)
ffmpeg_err("writing data to audio device failed\n"); ffmpeg_err("writing data to audio device failed\n");
av_freep(&output); av_freep(&output);
} }
@@ -748,10 +696,7 @@ static void FFMPEGThread(Context_t *context) {
avOut.height = 0; avOut.height = 0;
avOut.type = "audio"; avOut.type = "audio";
#ifdef reverse_playback_3 if (!context->playback->BackWard && context->output->audio->Write(context, &avOut) < 0)
if (!context->playback->BackWard)
#endif
if (context->output->audio->Write(context, &avOut) < 0)
{ {
ffmpeg_err("(aac) writing data to audio device failed\n"); ffmpeg_err("(aac) writing data to audio device failed\n");
} }
@@ -770,10 +715,7 @@ static void FFMPEGThread(Context_t *context) {
avOut.height = 0; avOut.height = 0;
avOut.type = "audio"; avOut.type = "audio";
#ifdef reverse_playback_3 if (!context->playback->BackWard && context->output->audio->Write(context, &avOut) < 0)
if (!context->playback->BackWard)
#endif
if (context->output->audio->Write(context, &avOut) < 0)
{ {
ffmpeg_err("writing data to audio device failed\n"); ffmpeg_err("writing data to audio device failed\n");
} }
@@ -1583,52 +1525,12 @@ static int container_ffmpeg_seek_bytes(off_t pos) {
return cERR_CONTAINER_FFMPEG_NO_ERROR; return cERR_CONTAINER_FFMPEG_NO_ERROR;
} }
#if !defined(use_sec_to_seek)
/* seeking relative to a given byteposition N bytes ->for reverse playback needed */
static int container_ffmpeg_seek_bytes_rel(off_t start, off_t bytes) {
int flag = AVSEEK_FLAG_BYTE;
off_t newpos;
off_t current_pos = avio_tell(avContext->pb);
if (start == -1)
start = current_pos;
ffmpeg_printf(250, "start:%lld bytes:%lld\n", start, bytes);
newpos = start + bytes;
if (current_pos > newpos)
flag |= AVSEEK_FLAG_BACKWARD;
if (newpos < 0)
{
ffmpeg_err("end of file reached\n");
return cERR_CONTAINER_FFMPEG_END_OF_FILE;
}
ffmpeg_printf(20, "seeking to position %lld (bytes)\n", newpos);
/* fixme: should we adapt INT64_MIN/MAX to some better value?
* take a loog in ffmpeg to be sure what this paramter are doing
*/
if (avformat_seek_file(avContext, -1, INT64_MIN, newpos, INT64_MAX, flag) < 0)
{
ffmpeg_err( "Error seeking\n");
return cERR_CONTAINER_FFMPEG_ERR;
}
ffmpeg_printf(30, "current_pos after seek %lld\n", avio_tell(avContext->pb));
return cERR_CONTAINER_FFMPEG_NO_ERROR;
}
#endif
/* seeking relative to a given byteposition N seconds ->for reverse playback needed */ /* seeking relative to a given byteposition N seconds ->for reverse playback needed */
static int container_ffmpeg_seek_rel(Context_t *context, off_t pos, long long int pts, float sec) { static int container_ffmpeg_seek_rel(Context_t *context, off_t pos, long long int pts, float sec) {
Track_t * videoTrack = NULL; Track_t * videoTrack = NULL;
Track_t * audioTrack = NULL; Track_t * audioTrack = NULL;
Track_t * current = NULL; Track_t * current = NULL;
int flag = 0; seek_target_flag = 0;
ffmpeg_printf(10, "seeking %f sec relativ to %lld\n", sec, pos); ffmpeg_printf(10, "seeking %f sec relativ to %lld\n", sec, pos);
@@ -1654,7 +1556,7 @@ static int container_ffmpeg_seek_rel(Context_t *context, off_t pos, long long in
pts = current->pts; pts = current->pts;
if (sec < 0) if (sec < 0)
flag |= AVSEEK_FLAG_BACKWARD; seek_target_flag |= AVSEEK_FLAG_BACKWARD;
getMutex(FILENAME, __FUNCTION__,__LINE__); getMutex(FILENAME, __FUNCTION__,__LINE__);
@@ -1683,12 +1585,8 @@ static int container_ffmpeg_seek_rel(Context_t *context, off_t pos, long long in
ffmpeg_printf(10, "1. seeking to position %lld bytes ->sec %f\n", pos, sec); ffmpeg_printf(10, "1. seeking to position %lld bytes ->sec %f\n", pos, sec);
if (container_ffmpeg_seek_bytes(pos) < 0) seek_target_bytes = pos;
{ do_seek_target_bytes = 1;
ffmpeg_err( "Error seeking\n");
releaseMutex(FILENAME, __FUNCTION__,__LINE__);
return cERR_CONTAINER_FFMPEG_ERR;
}
releaseMutex(FILENAME, __FUNCTION__,__LINE__); releaseMutex(FILENAME, __FUNCTION__,__LINE__);
return pos; return pos;
@@ -1702,35 +1600,8 @@ static int container_ffmpeg_seek_rel(Context_t *context, off_t pos, long long in
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 %f sec ->time base %f %d\n", sec, av_q2d(((AVStream*) current->stream)->time_base), AV_TIME_BASE);
#if 1 seek_target_seconds = sec * AV_TIME_BASE;
if (avformat_seek_file(avContext, -1, INT64_MIN, sec * AV_TIME_BASE, INT64_MAX, flag) < 0) do_seek_target_seconds = 1;
#else
if (av_seek_frame(avContext, -1 , sec * AV_TIME_BASE, flag) < 0)
#endif
{
ffmpeg_err( "Error seeking\n");
releaseMutex(FILENAME, __FUNCTION__,__LINE__);
return cERR_CONTAINER_FFMPEG_ERR;
}
context->output->Command(context, OUTPUT_FLUSH, NULL);
context->output->Command(context, OUTPUT_PLAY, NULL);
latestPts = 0;
#if 1
if (videoTrack && videoTrack->stream && ((AVStream*) videoTrack->stream)->codec && ((AVStream*) videoTrack->stream)->codec->codec)
avcodec_flush_buffers(((AVStream*) videoTrack->stream)->codec);
if (audioTrack && audioTrack->stream && ((AVStream*) audioTrack->stream)->codec && ((AVStream*) audioTrack->stream)->codec->codec)
avcodec_flush_buffers(((AVStream*) audioTrack->stream)->codec);
#endif
#if 0 // looks bogus --martii
if (sec <= 0)
{
ffmpeg_err("end of file reached\n");
releaseMutex(FILENAME, __FUNCTION__,__LINE__);
return cERR_CONTAINER_FFMPEG_END_OF_FILE;
}
#endif
} }
releaseMutex(FILENAME, __FUNCTION__,__LINE__); releaseMutex(FILENAME, __FUNCTION__,__LINE__);
@@ -1741,7 +1612,7 @@ static int container_ffmpeg_seek(Context_t *context, float sec, int absolute) {
Track_t * videoTrack = NULL; Track_t * videoTrack = NULL;
Track_t * audioTrack = NULL; Track_t * audioTrack = NULL;
Track_t * current = NULL; Track_t * current = NULL;
int flag = 0; seek_target_flag = 0;
if (absolute) { if (absolute) {
ffmpeg_printf(10, "goto %f sec\n", sec); ffmpeg_printf(10, "goto %f sec\n", sec);
@@ -1771,7 +1642,7 @@ static int container_ffmpeg_seek(Context_t *context, float sec, int absolute) {
} }
if (sec < 0) if (sec < 0)
flag |= AVSEEK_FLAG_BACKWARD; seek_target_flag |= AVSEEK_FLAG_BACKWARD;
getMutex(FILENAME, __FUNCTION__,__LINE__); getMutex(FILENAME, __FUNCTION__,__LINE__);
@@ -1808,12 +1679,8 @@ static int container_ffmpeg_seek(Context_t *context, float sec, int absolute) {
ffmpeg_printf(10, "1. seeking to position %lld bytes ->sec %f\n", pos, sec); ffmpeg_printf(10, "1. seeking to position %lld bytes ->sec %f\n", pos, sec);
if (container_ffmpeg_seek_bytes(pos) < 0) seek_target_bytes = pos;
{ do_seek_target_bytes = 1;
ffmpeg_err( "Error seeking\n");
releaseMutex(FILENAME, __FUNCTION__,__LINE__);
return cERR_CONTAINER_FFMPEG_ERR;
}
} else } else
{ {
@@ -1821,26 +1688,8 @@ static int container_ffmpeg_seek(Context_t *context, float sec, int absolute) {
sec += ((float) current->pts / 90000.0f); sec += ((float) current->pts / 90000.0f);
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 %f sec ->time base %f %d\n", sec, av_q2d(((AVStream*) current->stream)->time_base), AV_TIME_BASE);
#if 1 seek_target_seconds = sec * AV_TIME_BASE;
if (avformat_seek_file(avContext, -1, INT64_MIN, sec * AV_TIME_BASE, INT64_MAX, flag) < 0) do_seek_target_seconds = 1;
#else
if (av_seek_frame(avContext, -1 /* or streamindex */, sec * AV_TIME_BASE, flag) < 0)
#endif
{
ffmpeg_err( "Error seeking\n");
releaseMutex(FILENAME, __FUNCTION__,__LINE__);
return cERR_CONTAINER_FFMPEG_ERR;
}
context->output->Command(context, OUTPUT_FLUSH, NULL);
context->output->Command(context, OUTPUT_PLAY, NULL);
latestPts = 0;
#if 1
if (videoTrack && videoTrack->stream && ((AVStream*) videoTrack->stream)->codec && ((AVStream*) videoTrack->stream)->codec->codec)
avcodec_flush_buffers(((AVStream*) videoTrack->stream)->codec);
if (audioTrack && audioTrack->stream && ((AVStream*) audioTrack->stream)->codec && ((AVStream*) audioTrack->stream)->codec->codec)
avcodec_flush_buffers(((AVStream*) audioTrack->stream)->codec);
#endif
} }
releaseMutex(FILENAME, __FUNCTION__,__LINE__); releaseMutex(FILENAME, __FUNCTION__,__LINE__);

View File

@@ -609,59 +609,6 @@ int LinuxDvbFastForward(Context_t *context, char * type) {
int LinuxDvbReverse(Context_t *context __attribute__((unused)), char * type __attribute__((unused))) { int LinuxDvbReverse(Context_t *context __attribute__((unused)), char * type __attribute__((unused))) {
int ret = cERR_LINUXDVB_NO_ERROR; int ret = cERR_LINUXDVB_NO_ERROR;
#ifdef reverse_playback_2
int speed;
unsigned char video = !strcmp("video", type);
unsigned char audio = !strcmp("audio", type);
linuxdvb_printf(10, "v%d a%d\n", video, audio);
if (context->playback->Speed >= 0)
{
linuxdvb_err("error speed is greater 0, but should be a neg value in skipped frames (or zero)\n");
return cERR_LINUXDVB_ERROR;
}
/* speed == 0 indicates end of trick mode, otherwise negative value of skipped frames
* multiplicated with DVB_SPEED_NORMAL_PLAY (currently 1000)
*/
speed = (context->playback->Speed == 0) ? DVB_SPEED_REVERSE_STOPPED :
context->playback->Speed * DVB_SPEED_NORMAL_PLAY;
linuxdvb_printf(10, "speed %d - %d\n", speed, context->playback->Speed);
if (video && videofd != -1) {
getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
if (ioctl(videofd, VIDEO_SET_SPEED, speed) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("VIDEO_SET_SPEED: %s\n", strerror(errno));
ret = cERR_LINUXDVB_ERROR;
}
releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
}
if (audio && audiofd != -1) {
getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
if (ioctl(audiofd, AUDIO_SET_SPEED, speed) == -1)
{
linuxdvb_err("ioctl failed with errno %d\n", errno);
linuxdvb_err("AUDIO_SET_SPEED: %s\n", strerror(errno));
ret = cERR_LINUXDVB_ERROR;
}
releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__);
}
linuxdvb_printf(10, "exiting with value %d\n", ret);
#endif
return ret; return ret;
} }

View File

@@ -610,82 +610,6 @@ static int PlaybackFastForward(Context_t *context, int* speed) {
return ret; return ret;
} }
#ifdef reverse_playback_1
static pthread_t FBThread;
/* konfetti: see below */
static unsigned char isFBThreadStarted = 0;
static void FastBackwardThread(Context_t *context)
{
playback_printf(10, "\n");
context->output->Command(context, OUTPUT_AUDIOMUTE, "1");
while(context->playback && context->playback->isPlaying && context->playback->BackWard)
{
context->playback->isSeeking = 1;
context->output->Command(context, OUTPUT_CLEAR, NULL);
context->output->Command(context, OUTPUT_PAUSE, NULL);
context->output->Command(context, OUTPUT_CLEAR, NULL);
context->container->selectedContainer->Command(context, CONTAINER_SEEK, &context->playback->BackWard);
context->output->Command(context, OUTPUT_CLEAR, NULL);
context->playback->isSeeking = 0;
context->output->Command(context, OUTPUT_CONTINUE, NULL);
//context->container->selectedContainer->Command(context, CONTAINER_SEEK, &context->playback->BackWard);
//context->output->Command(context, OUTPUT_CLEAR, "video");
usleep(500000);
}
//context->output->Command(context, OUTPUT_CLEAR, NULL);
context->output->Command(context, OUTPUT_AUDIOMUTE, "0");
isFBThreadStarted = 0;
playback_printf(10, "exit\n");
}
static int PlaybackFastBackward(Context_t *context,int* speed) {
int ret = cERR_PLAYBACK_NO_ERROR;
int error;
pthread_attr_t attr;
playback_printf(10, "speed %d\n", *speed);
/* Audio only backwarding not supported */
if (context->playback->isVideo && !context->playback->isHttp && !context->playback->isForwarding && (!context->playback->isPaused || context->playback->isPlaying)) {
if ((*speed > 0) || (*speed < cMaxSpeed_fr))
{
playback_err("speed %d out of range (0 - %d) \n", *speed, cMaxSpeed_fr);
return cERR_PLAYBACK_ERROR;
}
context->playback->BackWard = -(*speed);
playback_printf(20, "Speed: %d x {%f}\n", *speed, context->playback->BackWard);
if(!isFBThreadStarted)
{
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
if((error = pthread_create(&FBThread, &attr, (void *)&FastBackwardThread, context)) != 0)
{
playback_err("Error creating thread error:%d:%s\n",error,strerror(error));
isFBThreadStarted = 0;
ret = cERR_PLAYBACK_ERROR;
} else
isFBThreadStarted = 1;
}
} else
{
playback_err("fast backward not possible\n");
ret = cERR_PLAYBACK_ERROR;
}
playback_printf(10, "exiting with value %d\n", ret);
return ret;
}
#else
static int PlaybackFastBackward(Context_t *context,int* speed) { static int PlaybackFastBackward(Context_t *context,int* speed) {
int ret = cERR_PLAYBACK_NO_ERROR; int ret = cERR_PLAYBACK_NO_ERROR;
@@ -734,8 +658,6 @@ static int PlaybackFastBackward(Context_t *context,int* speed) {
return ret; return ret;
} }
#endif
static int PlaybackSlowMotion(Context_t *context,int* speed) { static int PlaybackSlowMotion(Context_t *context,int* speed) {
int ret = cERR_PLAYBACK_NO_ERROR; int ret = cERR_PLAYBACK_NO_ERROR;