[FFmpeg-devel] [PATCH 2/2] MxPEG decoder
Anatoly Nenashev
anatoly.nenashev
Mon Nov 1 09:52:54 CET 2010
On 01.11.2010 03:31, Michael Niedermayer wrote:
> On Mon, Nov 01, 2010 at 02:56:50AM +0300, Anatoly Nenashev wrote:
>
>> On 01.11.2010 01:17, Michael Niedermayer wrote:
>>
>>> On Sun, Oct 31, 2010 at 09:23:13PM +0300, Anatoly Nenashev wrote:
>>>
>>>
>>>> Patch for .mxg demuxer
>>>>
>>>>
>>> [...]
>>>
>>>
>>>> +static int mxg_read_header(AVFormatContext *s, AVFormatParameters *ap)
>>>> +{
>>>> + AVStream *video_st = 0, *audio_st = 0;
>>>> + MXGContext *mxg = s->priv_data;
>>>> +
>>>> + /* video parameters will be extracted from the compressed bitstream */
>>>> + video_st = av_new_stream(s, VIDEO_STREAM_INDEX);
>>>> + if (!video_st)
>>>> + return AVERROR(ENOMEM);
>>>> + video_st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
>>>> + video_st->codec->codec_id = CODEC_ID_MXPEG;
>>>> + av_set_pts_info(video_st, 64, 1, 1000000);
>>>> +
>>>> + audio_st = av_new_stream(s, AUDIO_STREAM_INDEX);
>>>> + if (!audio_st)
>>>> + return AVERROR(ENOMEM);
>>>> + audio_st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
>>>> + audio_st->codec->codec_id = CODEC_ID_PCM_ALAW;
>>>> + audio_st->codec->channels = 1;
>>>> + audio_st->codec->sample_rate = 8000;
>>>> + audio_st->codec->bits_per_coded_sample = 8;
>>>> + audio_st->codec->block_align = 1;
>>>> +
>>>>
>>>>
>>>
>>>
>>>> + mxg->buffer = (uint8_t*) av_malloc(DEFAULT_PACKET_SIZE);
>>>>
>>>>
>>> unneeded cast
>>>
>>>
>> removed
>>
>>
>>> [...]
>>>
>>>
>>>> + if (mxg->found_video_packet) {
>>>> + mxg->buffer[mxg->current_pos++] = data;
>>>> + if (mxg->state == 0xfffe) {
>>>> + int size = get_be16(s->pb);
>>>> + if (url_feof(s->pb) || url_ferror(s->pb))
>>>> + return AVERROR_EOF;
>>>> + mxg->buffer = av_fast_realloc(mxg->buffer,&mxg->buffer_size,
>>>> + mxg->current_pos + size);
>>>>
>>>>
>>> here the + and similar at other points can overflow and lead to realloc to a
>>> too small buffer
>>>
>>>
>> fixed
>>
>>
>>> [...]
>>>
>>>
>>>> + if (mxg->current_pos>= mxg->buffer_size) {
>>>> + mxg->buffer = (uint8_t*) av_fast_realloc(mxg->buffer,&mxg->buffer_size,
>>>>
>>>>
>>> unneeded cast
>>>
>>>
>> removed
>>
>>
> [...]
>
>> +static int mxg_read_packet(AVFormatContext *s, AVPacket *pkt)
>> +{
>> + int ret, size;
>> + MXGContext *mxg = s->priv_data;
>> +
>> + while(!url_feof(s->pb)&& !url_ferror(s->pb)) {
>> + uint8_t data;
>> + int found_frame_end = 0;
>> +
>> + if (mxg->state == 0xffed) {
>> + size = get_be16(s->pb);
>> + if (url_feof(s->pb) || url_ferror(s->pb))
>> + return AVERROR_EOF;
>> + if (size<= 14)
>> + return AVERROR(EINVAL);
>> + url_fskip(s->pb, 12);
>> + if (url_feof(s->pb))
>> + return AVERROR_EOF;
>> + size -= 14;
>> + ret = av_get_packet(s->pb, pkt, size);
>> + if (ret< 0)
>> + return ret;
>> +
>> + pkt->stream_index = AUDIO_STREAM_INDEX;
>> + mxg->state = 0;
>> +
>> + return pkt->size;
>> + }
>> +
>> + data = get_byte(s->pb);
>> + mxg->state = (mxg->state<< 8) | data;
>> +
>> + if (mxg->found_video_packet) {
>> + mxg->buffer[mxg->current_pos++] = data;
>> + if (mxg->state == 0xfffe) {
>> + int size = get_be16(s->pb);
>> + if (url_feof(s->pb) || url_ferror(s->pb))
>> + return AVERROR_EOF;
>> +
>> + if (mxg->current_pos> mxg->current_pos + size)
>> + {
>> + av_log(s, AV_LOG_ERROR, "buffer overflow\n");
>> + return AVERROR(ENOMEM);
>> + }
>> + mxg->buffer = av_fast_realloc(mxg->buffer,&mxg->buffer_size,
>> + mxg->current_pos + size);
>> + if (!mxg->buffer) {
>> + av_log(s, AV_LOG_ERROR, "mxg demuxer error in av_fast_realloc()\n");
>> + return AVERROR(ENOMEM);
>> + }
>> + if (size< 2) {
>> + av_log(s, AV_LOG_ERROR, "wrong comment buffer size\n");
>> + return AVERROR(EINVAL);
>> + }
>> + mxg->buffer[mxg->current_pos++] = size>> 8;
>> + mxg->buffer[mxg->current_pos++] = size& 0xff;
>> +
>> + ret = get_buffer(s->pb, mxg->buffer + mxg->current_pos, size - 2);
>> + if (ret< 0)
>> + return ret;
>> + if (ret>= 16&& !strncmp(mxg->buffer + mxg->current_pos, "MXF", 3)) {
>> + mxg->dts = AV_RL64(mxg->buffer + mxg->current_pos + 8);
>> + }
>> + mxg->current_pos += ret;
>> + mxg->state = 0;
>> + } else if (mxg->state == 0xffd9) {
>> + found_frame_end = mxg->current_pos;
>> + mxg->current_pos = 0;
>> + mxg->found_video_packet = 0;
>> + } else if (mxg->state == 0xffd8) {
>> + //emulating frame end
>> + found_frame_end = mxg->current_pos - 2;
>> + mxg->current_pos = 2;
>> + mxg->found_video_packet = 1;
>> + } else if (mxg->state == 0xffed) {
>> + //emulating frame end
>> + found_frame_end = mxg->current_pos - 2;
>> + mxg->current_pos = 0;
>> + mxg->found_video_packet = 0;
>> + }
>> +
>> + if (found_frame_end) {
>> + ret = av_new_packet(pkt, found_frame_end);
>> + if (ret< 0)
>> + return ret;
>> + memcpy(pkt->data, mxg->buffer, found_frame_end);
>> + pkt->stream_index = VIDEO_STREAM_INDEX;
>> + pkt->dts = mxg->dts;
>> + return pkt->size;
>> + }
>> +
>> + if (mxg->current_pos>= mxg->buffer_size) {
>> + if (mxg->current_pos> mxg->current_pos + DEFAULT_PACKET_SIZE)
>> + {
>> + av_log(s, AV_LOG_ERROR, "buffer overflow\n");
>> + return AVERROR(ENOMEM);
>> + }
>> + mxg->buffer = av_fast_realloc(mxg->buffer,&mxg->buffer_size,
>> + mxg->current_pos + DEFAULT_PACKET_SIZE);
>> + if (!mxg->buffer) {
>> + av_log(s, AV_LOG_ERROR, "mxg demuxer error in av_fast_realloc()\n");
>> + return AVERROR(ENOMEM);
>> + }
>> + }
>> + } else if (mxg->state == 0xffd8){
>> + mxg->found_video_packet = 1;
>> + }
>>
> This loop is a bit oddly structured, is there a reason for this?
> id expect it to be more of the form
> while {
> state= (state<<8) + ...
>
> if(state ==)
> else if
> else if
> else
> }
>
> but its kind of convoluted with the audio code being before the state update
> then found_video_packet=1 and checks for that
>
>
Reimplemented. I hope that new version is more canonical.:-)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mxg_v3.patch
Type: text/x-patch
Size: 8283 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20101101/fb8b894e/attachment.bin>
More information about the ffmpeg-devel
mailing list