How to convert a JPEG image to an I-frame?

Message ID 47779C52.80805@cadsoft.de
State New
Headers

Commit Message

Klaus Schmidinger Dec. 30, 2007, 1:25 p.m. UTC
  On 12/27/07 14:53, Reinhard Nissl wrote:
> Hi,
> 
> Klaus Schmidinger schrieb:
> 
>> When I display field_test.mpg via DeviceStillPicture() on my FF DVB card
>> I see a picture that has a top and a bottom half that rapidly flicker
>> black and white (top black, bottom white and vice versa).
> 
> I've just verified this behavior on my EPIA VDR in the living room
> (which is connected to a 50 Hz TV set) by taking a photo.
> 
> The photo shows that the white lines are quite thick -- there is no gap
> between them. And the black area is totally black, i. e. the white area
> from the previous field has vanished already.
> 
>> After like half a second the picture gets static, and the top half is
>> solid black, while the bottom half is solid white.
> 
> I had a look into the FF card's driver implementation. The driver simply
> repeats the still image data for some time. And from your report I
> guess, that the FF card automatically displays two fields for each frame
> it receives. When the driver stops sending frames, the FF card displays
> the last field forever.
> 
> I also had a look into the hardware specification. It seems to me that
> the chip can be switched to a mode where it toggles between the fields
> automatically. But my coarse understanding of the driver tells me, that
> the driver doesn't make use of it.
> 
>> I never see anything like the field_test.png you posted (with alternating
>> black and white lines).

I followed your lead on the FREEZE command and found that when I change the
driver's av7110_av.c like this:

I get a smooth still picture (might need some thought on what to actually
use as the 'ret' value). And also your test image field_test.mpg displays
as shown in your field_test.png (after some short flicker, which apparently
comes from the phase where the frame is sent several times to fill up the
card's buffer).

Klaus
  

Comments

Reinhard Nissl Dec. 30, 2007, 1:51 p.m. UTC | #1
Hi,

Klaus Schmidinger schrieb:

>> I also had a look into the hardware specification. It seems to me that
>> the chip can be switched to a mode where it toggles between the fields
>> automatically. But my coarse understanding of the driver tells me, that
>> the driver doesn't make use of it.
> 
> I followed your lead on the FREEZE command and found that when I change the
> driver's av7110_av.c like this:
> 
> --- av7110_av.c 2007-12-30 12:59:44.204192651 +0100
> +++ av7110_av.c 2007-12-30 14:03:53.048848398 +0100
> @@ -1125,6 +1125,7 @@
>                 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
>                 ret = play_iframe(av7110, pic->iFrame, pic->size,
>                                   file->f_flags & O_NONBLOCK);
> +               ret = vidcom(av7110, AV_VIDEO_CMD_FREEZE, 1);
>                 break;
>         }
> 
> I get a smooth still picture (might need some thought on what to actually
> use as the 'ret' value). And also your test image field_test.mpg displays
> as shown in your field_test.png (after some short flicker, which apparently
> comes from the phase where the frame is sent several times to fill up the
> card's buffer).

I think sending the frame several times to the card should be omitted then.

Do you think there is the need to distinguish between progressive still
images and interlaced ones?

It might be reasonable to show a frame picture for progressive images
and only the last field picture for interlaced images.

Bye.
  
Klaus Schmidinger Dec. 30, 2007, 3:42 p.m. UTC | #2
On 12/30/07 14:51, Reinhard Nissl wrote:
> Hi,
> 
> Klaus Schmidinger schrieb:
> 
>>> I also had a look into the hardware specification. It seems to me that
>>> the chip can be switched to a mode where it toggles between the fields
>>> automatically. But my coarse understanding of the driver tells me, that
>>> the driver doesn't make use of it.
>> I followed your lead on the FREEZE command and found that when I change the
>> driver's av7110_av.c like this:
>>
>> --- av7110_av.c 2007-12-30 12:59:44.204192651 +0100
>> +++ av7110_av.c 2007-12-30 14:03:53.048848398 +0100
>> @@ -1125,6 +1125,7 @@
>>                 dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
>>                 ret = play_iframe(av7110, pic->iFrame, pic->size,
>>                                   file->f_flags & O_NONBLOCK);
>> +               ret = vidcom(av7110, AV_VIDEO_CMD_FREEZE, 1);
>>                 break;
>>         }
>>
>> I get a smooth still picture (might need some thought on what to actually
>> use as the 'ret' value). And also your test image field_test.mpg displays
>> as shown in your field_test.png (after some short flicker, which apparently
>> comes from the phase where the frame is sent several times to fill up the
>> card's buffer).
> 
> I think sending the frame several times to the card should be omitted then.

Tried that, but that doesn't work. Apparently the buffer(s) need to be filled
up before anything is displayed. Maybe they could be filled with something
else than repeating the actual frame data, thus avoiding the short flicker?

> Do you think there is the need to distinguish between progressive still
> images and interlaced ones?
> 
> It might be reasonable to show a frame picture for progressive images
> and only the last field picture for interlaced images.

I'm generating my images as "progressive" (at least that's what I think).
The command I'm using is

  mpeg2enc -f 3 -b 12500 -a 2 -q 1 -n p -I 0

which gives the best results so far. If I use '-I 1' to have it "interlaced",
the result looks just the same on the tv screen.

Klaus
  
Reinhard Nissl Dec. 30, 2007, 6:56 p.m. UTC | #3
Hi,

Klaus Schmidinger schrieb:

>> I think sending the frame several times to the card should be omitted then.
> 
> Tried that, but that doesn't work. Apparently the buffer(s) need to be filled
> up before anything is displayed. Maybe they could be filled with something
> else than repeating the actual frame data, thus avoiding the short flicker?

Hmm, does it work to switch the mode before sending the data?

>> Do you think there is the need to distinguish between progressive still
>> images and interlaced ones?
>>
>> It might be reasonable to show a frame picture for progressive images
>> and only the last field picture for interlaced images.
> 
> I'm generating my images as "progressive" (at least that's what I think).
> The command I'm using is
> 
>   mpeg2enc -f 3 -b 12500 -a 2 -q 1 -n p -I 0
> 
> which gives the best results so far. If I use '-I 1' to have it "interlaced",
> the result looks just the same on the tv screen.

Sure, but that's not what I've meant. The same function is being used to
 show the image for a cutting mark. Such an image would be interlaced.
On my EPIA, vdr-xine would display it as progressive, just as the FF
card would do with the changed driver. Don't know whether this matters.

Bye.
  
Klaus Schmidinger Dec. 30, 2007, 10:50 p.m. UTC | #4
On 12/30/07 19:56, Reinhard Nissl wrote:
> Hi,
> 
> Klaus Schmidinger schrieb:
> 
>>> I think sending the frame several times to the card should be omitted then.
>> Tried that, but that doesn't work. Apparently the buffer(s) need to be filled
>> up before anything is displayed. Maybe they could be filled with something
>> else than repeating the actual frame data, thus avoiding the short flicker?
> 
> Hmm, does it work to switch the mode before sending the data?
> 
>>> Do you think there is the need to distinguish between progressive still
>>> images and interlaced ones?
>>>
>>> It might be reasonable to show a frame picture for progressive images
>>> and only the last field picture for interlaced images.
>> I'm generating my images as "progressive" (at least that's what I think).
>> The command I'm using is
>>
>>   mpeg2enc -f 3 -b 12500 -a 2 -q 1 -n p -I 0
>>
>> which gives the best results so far. If I use '-I 1' to have it "interlaced",
>> the result looks just the same on the tv screen.
> 
> Sure, but that's not what I've meant. The same function is being used to
>  show the image for a cutting mark. Such an image would be interlaced.
> On my EPIA, vdr-xine would display it as progressive, just as the FF
> card would do with the changed driver. Don't know whether this matters.

When I jump to an editing mark with the modified driver, the display
is just as smooth as when displaying a still image generated from a
jpeg file. So the driver modification also improves this area.

Klaus
  
Klaus Schmidinger Dec. 31, 2007, 4:17 p.m. UTC | #5
On 12/30/07 19:56, Reinhard Nissl wrote:
> Hi,
> 
> Klaus Schmidinger schrieb:
> 
>>> I think sending the frame several times to the card should be omitted then.
>> Tried that, but that doesn't work. Apparently the buffer(s) need to be filled
>> up before anything is displayed. Maybe they could be filled with something
>> else than repeating the actual frame data, thus avoiding the short flicker?
> 
> Hmm, does it work to switch the mode before sending the data?

If I call vidcom(av7110, AV_VIDEO_CMD_FREEZE, 1) before play_iframe(),
I get a black screen for the first picture. Only after switching to the next
picture do I see something on the screen.
So apparently it must be called afterwards.

Klaus
  
Joachim Wilke April 20, 2008, 7:53 p.m. UTC | #6
2007/12/31, Klaus Schmidinger <Klaus.Schmidinger@cadsoft.de>:
> If I call vidcom(av7110, AV_VIDEO_CMD_FREEZE, 1) before play_iframe(),
>  I get a black screen for the first picture. Only after switching to the next
>  picture do I see something on the screen.
>  So apparently it must be called afterwards.

Great work! Has this patch already found its way into the dvb drivers?
  
Wolfgang Rohdewald April 21, 2008, 12:30 p.m. UTC | #7
On Sonntag, 20. April 2008, Joachim Wilke wrote:
> Great work! Has this patch already found its way into the dvb drivers?

I dont know when it got in, but kernel 2.6.25 has it.
  

Patch

--- av7110_av.c 2007-12-30 12:59:44.204192651 +0100
+++ av7110_av.c 2007-12-30 14:03:53.048848398 +0100
@@ -1125,6 +1125,7 @@ 
                dvb_ringbuffer_flush_spinlock_wakeup(&av7110->avout);
                ret = play_iframe(av7110, pic->iFrame, pic->size,
                                  file->f_flags & O_NONBLOCK);
+               ret = vidcom(av7110, AV_VIDEO_CMD_FREEZE, 1);
                break;
        }