[FFmpeg-devel] [PATCH 1/2] MxPEG decoder
Anatoly Nenashev
anatoly.nenashev
Mon Feb 14 13:46:28 CET 2011
On 14.02.2011 14:51, M?ns Rullg?rd wrote:
> Anatoly Nenashev<anatoly.nenashev at ovsoft.ru> writes:
>
>
>>
>> +static int mjpeg_allocate_picture(MJpegDecodeContext *s, AVFrame* picture_ptr,
>> + int key_frame, int reference_frame)
>>
> Style nit: please keep stars attached to variable names, like this:
> AVFrame *picture_ptr
>
>
>> +{
>> + int i;
>> +
>> + if (picture_ptr->data[0])
>> + s->avctx->release_buffer(s->avctx, picture_ptr);
>> +
>> + picture_ptr->reference = reference_frame;
>> + if (s->avctx->get_buffer(s->avctx, picture_ptr)< 0) {
>> + av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
>> + return -1;
>> + }
>> + picture_ptr->pict_type = key_frame ? FF_I_TYPE : FF_P_TYPE;
>> + picture_ptr->key_frame = key_frame;
>> + s->got_picture = 1;
>> +
>> + for (i = 0; i< MAX_COMPONENTS; i++) {
>> + s->linesize[i] = picture_ptr->linesize[i]<< s->interlaced;
>> + }
>> +}
>>
> Is this purely factored out of the code below? If so, separating such
> changes into a preparatory patch would make the main patch easier to
> read. If it's not too much trouble...
>
>
I will try to do it this way in new review thread which I've created.
>> + reference_ptr =&mxctx->pictures[mxctx->picture_index ^ 1];
>> + if (!reference_ptr->data[0]) {
>> + av_log(s->avctx, AV_LOG_WARNING, "No reference picture data for non-key frame, skipping\n");
>> + return -1;
>> + }
>> +
>> + picture_ptr =&mxctx->pictures[mxctx->picture_index];
>> + if (mjpeg_allocate_picture(s, picture_ptr, 0, 1)< 0)
>> + return -1;
>> +
>> + return 0;
>> +}
>> +
>> int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
>> {
>> int len, nb_components, i, width, height, pix_fmt_id;
>> + AVFrame *picture_ptr;
>> + MXpegDecodeContext *mxctx = (s->avctx->codec_id == CODEC_ID_MXPEG) ? s->avctx->priv_data : 0;
>>
> I'd prefer if you did this a bit differently. More on that below.
>
>
>> + if (mxctx) {
>> + mxctx->got_sof_data = 0;
>> + if (s->lossless) {
>> + av_log(s->avctx, AV_LOG_ERROR, "Lossless mode doesn't available in MxPEG\n");
>>
> Bad grammar.
>
Sorry.
>> s->coefs_finished[c] |= 1;
>> if(s->flipped) {
>> @@ -794,12 +862,15 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, i
>>
>> for(mb_y = 0; mb_y< s->mb_height; mb_y++) {
>> for(mb_x = 0; mb_x< s->mb_width; mb_x++) {
>> + const int copy_mb = use_mxm_bitmask&& !get_bits1(&mxm_bitmask_gb);
>>
> Indexing the bit directly is probably faster than using get_bits.
> Something like bitmask[idx>>3]& (128>> (idx& 7)) should do it.
> Also, what happens if the bitmask is smaller than the full frame?
>
> If this is allowed, the easiest way to handle it is probably to allocate
> a larger bitmask buffer and pad it with zeros.
>
>
Ok. I will try.
>> +static int mxpeg_decode_mxm(AVCodecContext *avctx, MXpegDecodeContext *mxctx,
>> + char *buf, int len)
>> +{
>> + int32_t bitmask_size, i;
>> + uint32_t mb_count;
>>
> Why do you use sized types here? For local variables it is almost
> always better to use plain int or unsigned int types.
>
>
I'm not sure that sizeof(int) >= 4 in all architectures supported by
FFmpeg. Correct me if I wrong.
>> + av_freep(&mxctx->comment_buffer);
>> + mxctx->comment_buffer = buf;
>> + mxctx->mxm_bitmask = buf + 12;
>> +
>> + mxctx->mb_width = AV_RL16(&buf[4]);
>> + mxctx->mb_height = AV_RL16(&buf[6]);
>> + mb_count = (uint32_t)mxctx->mb_width * mxctx->mb_height;
>>
> Why the cast?
>
>
This is also about sizeof(int).
>> + if (!mb_count || mb_count> 0x7FFFFFF8) {
>>
> This looks strange. What condition are you actually trying to check for?
>
>
This is a check for possible overflow of (mb_count + 7) value.
>> diff --git a/libavcodec/mjpegdec.h b/libavcodec/mjpegdec.h
>> index 7baa5dc..24597d5 100644
>> --- a/libavcodec/mjpegdec.h
>> +++ b/libavcodec/mjpegdec.h
>> @@ -107,6 +107,19 @@ typedef struct MJpegDecodeContext {
>> unsigned int ljpeg_buffer_size;
>> } MJpegDecodeContext;
>>
>> +typedef struct MXpegDecodeContext {
>> + MJpegDecodeContext jpgctx;
>> + int got_sof_data; /* true if SOF data successfully parsed */
>> + uint8_t *comment_buffer; /* temporary comment buffer */
>> + uint8_t *mxm_bitmask; /* bitmask buffer */
>> + int32_t bitmask_size; /* size of bitmask */
>> + uint8_t has_complete_frame; /* true if has complete frame */
>> + uint8_t *completion_bitmask; /* completion bitmask of macroblocks */
>> + int mb_width, mb_height; /* size of picture in MB's from MXM header */
>>
> Are these different from the fields with the same names in MJpegDecodeContext?
>
>
>> + AVFrame pictures[2]; /* pictures array */
>> + int picture_index; /* index of current picture, other picture is reference */
>> +} MXpegDecodeContext;
>>
> I would add these, apart from pictures[], to the end of
> MJpegDecodeContext and make the existing picture there an array of two
> instead.
>
>
Ok. I will add these fields in MJpegDecodeContext.
More information about the ffmpeg-devel
mailing list