Esempio n. 1
0
static int
tsmf_ffmpeg_init_stream(ITSMFDecoder * decoder, const TS_AM_MEDIA_TYPE * media_type)
{
	TSMFFFmpegDecoder * mdecoder = (TSMFFFmpegDecoder *) decoder;
	uint32 size;
	const uint8 * s;
	uint8 * p;

	mdecoder->codec = avcodec_find_decoder(mdecoder->codec_id);
	if (!mdecoder->codec)
	{
		LLOGLN(0, ("tsmf_ffmpeg_init_stream: avcodec_find_decoder failed."));
		return 1;
	}

	mdecoder->codec_context->codec_id = mdecoder->codec_id;
	mdecoder->codec_context->codec_type = mdecoder->media_type;

	if (mdecoder->media_type == AVMEDIA_TYPE_VIDEO)
	{
		if (tsmf_ffmpeg_init_video_stream(decoder, media_type))
			return 1;
	}
	else if (mdecoder->media_type == AVMEDIA_TYPE_AUDIO)
	{
		if (tsmf_ffmpeg_init_audio_stream(decoder, media_type))
			return 1;
	}

	if (media_type->ExtraData)
	{
		if (media_type->SubType == TSMF_SUB_TYPE_AVC1 &&
			media_type->FormatType == TSMF_FORMAT_TYPE_MPEG2VIDEOINFO)
		{
			/* The extradata format that FFmpeg uses is following CodecPrivate in Matroska.
			   See http://haali.su/mkv/codecs.pdf */
			mdecoder->codec_context->extradata_size = media_type->ExtraDataSize + 8;
			mdecoder->codec_context->extradata = malloc(mdecoder->codec_context->extradata_size);
			p = mdecoder->codec_context->extradata;
			*p++ = 1; /* Reserved? */
			*p++ = media_type->ExtraData[8]; /* Profile */
			*p++ = 0; /* Profile */
			*p++ = media_type->ExtraData[12]; /* Level */
			*p++ = 0xff; /* Flag? */
			*p++ = 0xe0 | 0x01; /* Reserved | #sps */
			s = media_type->ExtraData + 20;
			size = ((uint32)(*s)) * 256 + ((uint32)(*(s + 1)));
			memcpy(p, s, size + 2);
			s += size + 2;
			p += size + 2;
			*p++ = 1; /* #pps */
			size = ((uint32)(*s)) * 256 + ((uint32)(*(s + 1)));
			memcpy(p, s, size + 2);
		}
		else
		{
			/* Add a padding to avoid invalid memory read in some codec */
			mdecoder->codec_context->extradata_size = media_type->ExtraDataSize + 8;
			mdecoder->codec_context->extradata = malloc(mdecoder->codec_context->extradata_size);
			memcpy(mdecoder->codec_context->extradata, media_type->ExtraData, media_type->ExtraDataSize);
			memset(mdecoder->codec_context->extradata + media_type->ExtraDataSize, 0, 8);
		}
	}

	if (mdecoder->codec->capabilities & CODEC_CAP_TRUNCATED)
		mdecoder->codec_context->flags |= CODEC_FLAG_TRUNCATED;

	return 0;
}
Esempio n. 2
0
static BOOL tsmf_ffmpeg_init_stream(ITSMFDecoder* decoder, const TS_AM_MEDIA_TYPE *media_type)
{
	BYTE *p;
	UINT32 size;
	const BYTE *s;
	TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder;

	mdecoder->codec = avcodec_find_decoder(mdecoder->codec_id);
	if (!mdecoder->codec)
	{
		WLog_ERR(TAG, "avcodec_find_decoder failed.");
		return FALSE;
	}

	mdecoder->codec_context->codec_id = mdecoder->codec_id;
	mdecoder->codec_context->codec_type = mdecoder->media_type;
	switch(mdecoder->media_type)
	{
		case AVMEDIA_TYPE_VIDEO:
			if (!tsmf_ffmpeg_init_video_stream(decoder, media_type))
				return FALSE;
			break;
		case AVMEDIA_TYPE_AUDIO:
			if (!tsmf_ffmpeg_init_audio_stream(decoder, media_type))
				return FALSE;
			break;
		default:
			WLog_ERR(TAG, "unknown media_type %d", mdecoder->media_type);
			break;
	}

	if (media_type->ExtraData)
	{
		/* Add a padding to avoid invalid memory read in some codec */
		mdecoder->codec_context->extradata_size = media_type->ExtraDataSize + 8;
		mdecoder->codec_context->extradata = calloc(1, mdecoder->codec_context->extradata_size);
		if (!mdecoder->codec_context->extradata)
			return FALSE;

		if (media_type->SubType == TSMF_SUB_TYPE_AVC1 &&
				media_type->FormatType == TSMF_FORMAT_TYPE_MPEG2VIDEOINFO)
		{
			/* The extradata format that FFmpeg uses is following CodecPrivate in Matroska.
			   See http://haali.su/mkv/codecs.pdf */
			p = mdecoder->codec_context->extradata;
			*p++ = 1; /* Reserved? */
			*p++ = media_type->ExtraData[8]; /* Profile */
			*p++ = 0; /* Profile */
			*p++ = media_type->ExtraData[12]; /* Level */
			*p++ = 0xff; /* Flag? */
			*p++ = 0xe0 | 0x01; /* Reserved | #sps */
			s = media_type->ExtraData + 20;
			size = ((UINT32)(*s)) * 256 + ((UINT32)(*(s + 1)));
			memcpy(p, s, size + 2);
			s += size + 2;
			p += size + 2;
			*p++ = 1; /* #pps */
			size = ((UINT32)(*s)) * 256 + ((UINT32)(*(s + 1)));
			memcpy(p, s, size + 2);
		}
		else
		{
			memcpy(mdecoder->codec_context->extradata, media_type->ExtraData, media_type->ExtraDataSize);
			memset(mdecoder->codec_context->extradata + media_type->ExtraDataSize, 0, 8);
		}
	}

	if (mdecoder->codec->capabilities & CODEC_CAP_TRUNCATED)
		mdecoder->codec_context->flags |= CODEC_FLAG_TRUNCATED;
	return TRUE;
}