Beispiel #1
0
static int32_t ffmpeg_read(void *opaque, uint8_t *buf, int32_t buf_size)
{
	int32_t sumlen = 0;
	int32_t len = 0;
	int32_t count = 2000;

	while (sumlen < buf_size && (--count) > 0 && 0 == PlaybackDieNow(0))
	{
		len = ffmpeg_read_real(opaque, buf, buf_size - sumlen);
		sumlen += len;
		buf += len;
		if (len == 0)
		{
			usleep(10000);
		}
	}
	if (count == 0)
	{
		if (sumlen == 0)
		{
			ffmpeg_err( "Timeout waiting for buffered data (buf_size=%d sumlen=%d)!\n", buf_size, sumlen);
		}
		else
		{
			ffmpeg_err( "Timeout, not all buffered data availabel (buf_size=%d sumlen=%d)!\n", buf_size, sumlen);
		}
	}
	return sumlen;
}
static AVCodecContext *wrapped_avcodec_get_context(uint32_t cAVIdx, AVStream *stream)
{
#if (LIBAVFORMAT_VERSION_MAJOR > 57) || ((LIBAVFORMAT_VERSION_MAJOR == 57) && (LIBAVFORMAT_VERSION_MINOR > 32))
    AVCodecContext *avCodecCtx = restore_avcodec_context(cAVIdx, stream->id);
    if (!avCodecCtx)
    {
        avCodecCtx = avcodec_alloc_context3(NULL);
        if (!avCodecCtx) 
        {
            ffmpeg_err("context3 alloc for stream %d failed\n", (int)stream->id);
            return NULL;
        }

        if (avcodec_parameters_to_context(avCodecCtx, stream->codecpar) < 0)
        {
            ffmpeg_err("parameters to context for stream %d failed\n", (int)stream->id);
            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);

        return avCodecCtx;
    }
#else
    return stream->codec;
#endif
}
Beispiel #3
0
static int64_t ffmpeg_seek(void *opaque, int64_t offset, int32_t whence)
{
	int64_t diff;
	int32_t rwdiff = 0;
	whence &= ~AVSEEK_FORCE;

	if (whence != SEEK_CUR && whence != SEEK_SET)
	{
		return AVERROR(EINVAL);
	}
	if (whence == SEEK_CUR)
	{
		diff = offset;
	}
	else
	{
		diff = offset - avContextTab[0]->pb->pos;
	}

	if (diff == 0)
	{
		return avContextTab[0]->pb->pos;
	}
	getfillerMutex(__FILE__, __FUNCTION__,__LINE__);

	if (ffmpeg_buf_read < ffmpeg_buf_write)
	{
		rwdiff = ffmpeg_buf_write - ffmpeg_buf_read;
	}
	if (ffmpeg_buf_read > ffmpeg_buf_write)
	{
		rwdiff = (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_read;
		rwdiff += ffmpeg_buf_write - ffmpeg_buf;
	}
	if (diff > 0 && diff < rwdiff)
	{
		/* can do the seek inside the buffer */
		ffmpeg_printf(20, "buffer-seek diff=%lld\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));
		}
		else
		{
			ffmpeg_buf_read = ffmpeg_buf_read + diff;
		}
	}
	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);
		int32_t tmpdiff = diff * -1;
		if (tmpdiff > ffmpeg_buf_read - ffmpeg_buf)
		{
			ffmpeg_buf_read = (ffmpeg_buf + ffmpeg_buf_size) - (tmpdiff - (ffmpeg_buf_read - ffmpeg_buf));
		}
		else
		{
			ffmpeg_buf_read = ffmpeg_buf_read - tmpdiff;
		}
	}
	else
	{
		releasefillerMutex(__FILE__, __FUNCTION__,__LINE__);
		ffmpeg_printf(20, "real-seek diff=%lld\n", diff);

		ffmpeg_do_seek_ret = 0;
		ffmpeg_do_seek = diff;
		while (ffmpeg_do_seek != 0)
		{
			usleep(100000);
		}
		ffmpeg_do_seek = 0;
		if (ffmpeg_do_seek_ret < 0)
		{
			ffmpeg_err("seek not ok ret=%d\n", ffmpeg_do_seek_ret);
			return ffmpeg_do_seek_ret;
		}

		//fill buffer
		int32_t count = ffmpeg_buf_seek_time * 10;
		int32_t size = 0;

		container_get_fillbufstatus(&size);
		while (size < ffmpeg_buf_size - FILLBUFDIFF && (--count) > 0)
		{
			usleep(100000);
			container_get_fillbufstatus(&size);
		}
		return avContextTab[0]->pb->pos + diff;
	}
	releasefillerMutex(__FILE__, __FUNCTION__,__LINE__);
	return avContextTab[0]->pb->pos + diff;
}
Beispiel #4
0
//flag 0: start direct
//flag 1: from thread
static void ffmpeg_filler(Context_t *context, int32_t id, int32_t* inpause, int32_t flag)
{
	int32_t len = 0;
	int32_t rwdiff = ffmpeg_buf_size;
	uint8_t buf[FILLBUFPAKET];

	if (ffmpeg_read_org == NULL || ffmpeg_seek_org == NULL)
	{
		ffmpeg_err("ffmpeg_read_org or ffmpeg_seek_org is NULL\n");
		return;
	}

	while ((flag == 0 && avContextTab[0] != NULL && avContextTab[0]->pb != NULL && rwdiff > FILLBUFDIFF)
	   ||  (flag == 1 && hasfillerThreadStarted[id] == 1 && avContextTab[0] != NULL && avContextTab[0]->pb != NULL && rwdiff > FILLBUFDIFF))
	{
		 if ( 0 == PlaybackDieNow(0))
		 {
			break;
		 }
		 if (flag == 0 && ffmpeg_buf_stop == 1)
		 {
			 ffmpeg_buf_stop = 0;
			 break;
		 }
		 getfillerMutex(__FILE__, __FUNCTION__,__LINE__);
		 //do a seek
		 if (ffmpeg_do_seek != 0)
		 {
			 ffmpeg_do_seek_ret = ffmpeg_seek_org(avContextTab[0]->pb->opaque, avContextTab[0]->pb->pos + ffmpeg_do_seek, SEEK_SET);
			 if (ffmpeg_do_seek_ret >= 0)
			 {
				 ffmpeg_buf_write = ffmpeg_buf;
				 ffmpeg_buf_read = ffmpeg_buf;
			 }
			 ffmpeg_do_seek = 0;
		 }
		 if (ffmpeg_buf_read == ffmpeg_buf_write)
		 {
			 ffmpeg_buf_valid_size = 0;
			 rwdiff = ffmpeg_buf_size;
		 }
		 if (ffmpeg_buf_read < ffmpeg_buf_write)
		 {
			 rwdiff = (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_write;
			 rwdiff += ffmpeg_buf_read - ffmpeg_buf;
		 }
		 if (ffmpeg_buf_read > ffmpeg_buf_write)
		 {
			rwdiff = ffmpeg_buf_read - ffmpeg_buf_write;
		 }
		 int32_t size = FILLBUFPAKET;
		 if (rwdiff - FILLBUFDIFF < size)
		 {
			 size = (rwdiff - FILLBUFDIFF);
		 }

		 if (ffmpeg_buf_write + size > ffmpeg_buf + ffmpeg_buf_size)
		 {
			 size = (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_write;
		 }
		 if (ffmpeg_buf_write == ffmpeg_buf + ffmpeg_buf_size)
		 {
			 ffmpeg_buf_write = ffmpeg_buf;
		 }
		 releasefillerMutex(__FILE__, __FUNCTION__,__LINE__);

		 if (size > 0)
		 {
			 if (flag == 1 && hasfillerThreadStarted[id] == 2)
			{
				break;
			}
			len = ffmpeg_read_org(avContextTab[0]->pb->opaque, buf, size);
			if (flag == 1 && hasfillerThreadStarted[id] == 2)
			{
				break;
			}
			ffmpeg_printf(20, "buffer-status (free buffer=%d)\n", rwdiff - FILLBUFDIFF - len);

			getfillerMutex(__FILE__, __FUNCTION__,__LINE__);
			if (len > 0)
			{
				memcpy(ffmpeg_buf_write, buf, len);
				ffmpeg_buf_write += len;
			}
			else
			{
				releasefillerMutex(__FILE__, __FUNCTION__,__LINE__);
				ffmpeg_err("read not ok ret=%d\n", len);
			 	break;
			 }
			 releasefillerMutex(__FILE__, __FUNCTION__,__LINE__);
		}
		else
		{
			//on long pause the server close the connection, so we use seek to reconnect
			if (context != NULL && context->playback != NULL && inpause != NULL)
			{
				if ((*inpause) == 0 && context->playback->isPaused)
				{
					(*inpause) = 1;
				}
				else if ((*inpause) == 1 && !context->playback->isPaused)
				{
					int32_t buflen = 0;
					(*inpause) = 0;

					getfillerMutex(__FILE__, __FUNCTION__,__LINE__);
					if (ffmpeg_buf_read < ffmpeg_buf_write)
					{
						buflen = ffmpeg_buf_write - ffmpeg_buf_read;
					}
					if (ffmpeg_buf_read > ffmpeg_buf_write)
					{
						buflen = (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_read;
						buflen += ffmpeg_buf_write - ffmpeg_buf;
					} 
					ffmpeg_seek_org(avContextTab[0]->pb->opaque, avContextTab[0]->pb->pos + buflen, SEEK_SET);
					releasefillerMutex(__FILE__, __FUNCTION__,__LINE__);
				}
			}
		}
	}
}