Oh yes. I also tried it with values in the range 1 & 31 and no difference.
Clive -----Original Message----- From: [email protected] [mailto:[email protected]] On Behalf Of Clive Taylor Sent: 02 April 2009 14:46 To: Libav* user questions and discussions Subject: Re: [libav-user] Writing single frames to JPEG Stas, It's beginning to look as though setting the quality in the codec context sets it for the duration of the codec instance's lifetime. OK that sentence isn't very clear, but what I've tried to do is to read one particular frame and then to write it out at different quality settings. What I did was something like this: // // Allocate the output codec context // pOCodecCtx = avcodec_alloc_context ( ); if ( !pOCodecCtx ) { printf ( "Unable to allocate output codec context.\n" ); av_free ( pFrameRGB ); av_free ( pFrame ); avcodec_close ( pCodecCtx ); av_close_input_file ( pFormatCtx ); exit ( 2 ); } // // Initialise format parameters // pOCodecCtx->bit_rate = pCodecCtx->bit_rate; pOCodecCtx->width = pCodecCtx->width; pOCodecCtx->height = pCodecCtx->height; pOCodecCtx->pix_fmt = ImgFmt; pOCodecCtx->codec_id = CODEC_ID_MJPEG; pOCodecCtx->codec_type = CODEC_TYPE_VIDEO; pOCodecCtx->time_base.num = pCodecCtx->time_base.num; pOCodecCtx->time_base.den = pCodecCtx->time_base.den; // // Allocate the JPEG encoder // pOCodec = avcodec_find_encoder ( pOCodecCtx->codec_id ); if ( !pOCodec ) { printf ( "Unable to find JPEG encoder.\n" ); av_free ( pFrameRGB ); av_free ( pFrame ); avcodec_close ( pCodecCtx ); av_close_input_file ( pFormatCtx ); exit ( 2 ); } // // Open the JPEG encoder // if ( avcodec_open ( pOCodecCtx, pOCodec ) < 0 ) { printf ( "Unable to open JPEG encoder.\n" ); av_free ( pFrameRGB ); av_free ( pFrame ); avcodec_close ( pCodecCtx ); av_close_input_file ( pFormatCtx ); exit ( 2 ); } That gets me the JPEG encoder. Inside a "while ( 1 )" loop, I then do this if ( !GetNextFrame ( pFormatCtx, pCodecCtx, VideoStream, pFrame, i ) ) break; #ifdef DOJPEG if ( (UFrameInt == -1) && (i == 8000) ) { for ( QNo = 1; QNo < 100; QNo++ ) { // // Encode the frame as a JPEG image // pFrame->pts = i + QNo; pOCodecCtx->qmin = pOCodecCtx->qmax = (100 - QNo) * FF_LAMBDA_MAX / 100; pOCodecCtx->mb_lmin = pOCodecCtx->lmin = pOCodecCtx->qmin * FF_QP2LAMBDA; pOCodecCtx->mb_lmax = pOCodecCtx->lmax = pOCodecCtx->qmax * FF_QP2LAMBDA; pOCodecCtx->flags = CODEC_FLAG_QSCALE; pFrame->quality = pOCodecCtx->global_quality = pOCodecCtx->qmin * FF_QP2LAMBDA; BufSizActual = avcodec_encode_video ( pOCodecCtx, Buffer, BufSiz, pFrame ); // // Write JPEG to file // sprintf ( JPEGFName, "f%06dq%02d.jpg", i, QNo ); JPEGFile = fopen ( JPEGFName, "wb" ); fwrite ( Buffer, 1, BufSizActual, JPEGFile ); fclose ( JPEGFile ); } } else #endif // def DOJPEG // // Do something else // In this code, i is the frame counter, UFrameInt is just a value set on the command line (in this case to -1) and GetNextFrame ( ) is a wrapper around av_read_frame ( ). It was a lot tidier before I put it into this e-mail, too. So, what I'm trying to do is to set all quality values from 1% to 99% and write them out to files whose name reflects the frame number and the quality (f008000q01.jpg - f008000q99.jpg). I'm using an IDE (don't tell anyone, but it's Microsoft Visual Studio 6) so I can watch the qmin and qmax values as they change, and I can see the size of the output buffer for each setting of the quality and other VBR values. In the case of the video file that I'm using here, I always get a buffer size of 11556 bytes, no matter what the global_quality, qmin, qmax, lmin, lmax, mb_lmin and mb_lmax elements of the codec context are set to. >From this, I'd guess that there's something else that needs to be changed or set somewhere, or that the encoder has to be closed and reopened for each quality value change and the data is not treated as dynamic. It's almost tempting to tell the customer that they need to use a hardware JPEG encoder, 'cause it'd be a damned sight cheaper than having to pay me to do all of these experiments, but a) I did quite lot of work with early CCube encoders (late 1980s, early 1990s) and they weren't much fun either, and b) I need the money. Clive -----Original Message----- From: [email protected] [mailto:[email protected]] On Behalf Of Stas Oskin Sent: 02 April 2009 12:46 To: Libav* user questions and discussions Subject: Re: [libav-user] Writing single frames to JPEG > > Oh and the following comment in AVCodec.h > > /**\ > * quality (between 1 (good) and FF_LAMBDA_MAX (bad)) \ > * - encoding: set by libavcodec. For coded_picture (and set by user for > input).\ > > And so on. It's round about line 607 in avcodec.h > > Clive > Anyone? :) _______________________________________________ libav-user mailing list [email protected] https://lists.mplayerhq.hu/mailman/listinfo/libav-user _______________________________________________ libav-user mailing list [email protected] https://lists.mplayerhq.hu/mailman/listinfo/libav-user _______________________________________________ libav-user mailing list [email protected] https://lists.mplayerhq.hu/mailman/listinfo/libav-user
