Hi,
Darren Salt wrote:
Cool -- are you relying on XINE_STREAM_INFO_VIDEO_AFD?
Yes.
My implementation in libmpeg2 is not perfect. It lacks stacking (AFD
information may be valid for a sequence, group or frame, i. e. the AFD for
a sequence could be overridden for a single frame duration by a frame AFD)
and cannot detect XINE_VIDEO_AFD_NOT_PRESENT.
My code is currently broken wrt some transitions and when paused, but this
could be an effect of breakage in your code. (I'm attaching the patch for
reference.)
Would you provide me a sample stream which contains some transitions
between different XINE_VIDEO_AFD_* values?
http://zap.tartarus.org/~ds/001.vdr> is a short clip with one transition
and a corresponding aspect change - AFD 14 to AFD 9, 16:9 to 4:3.
The attached patch against xine-lib-cvs/src/libmpeg2 fixes the above
mentioned issues (and contains the vdr-xine changes, too).
decode.c contains two fprintf() debug statements: one reports the
detected AFD value and whether it was detected at [S]equence, [G]roup or
[P]icture level. The other statement reports AFD changes.
Be aware that AFD changes are detected in decoding order of the
pictures. Further changes would be necessary to have them reported in
display order (see comment in decode.c).
Bye.
--
Dipl.-Inform. (FH) Reinhard Nissl
mailto:[EMAIL PROTECTED]
--- xine-cvs/xine-lib/src/libmpeg2/decode.c 2006-12-09 22:04:30.0 +0100
+++ xine-lib/src/libmpeg2/decode.c 2006-12-15 23:24:46.0 +0100
@@ -87,6 +87,13 @@ void mpeg2_init (mpeg2dec_t * mpeg2dec,
mpeg2dec->code = 0xb4;
mpeg2dec->seek_mode = 0;
+/* initialize AFD storage */
+mpeg2dec->afd_stack[0] = -1;
+mpeg2dec->afd_stack[1] = -1;
+mpeg2dec->afd_stack[2] = -1;
+mpeg2dec->afd_index = -1;
+mpeg2dec->afd_value = -2;
+
memset (mpeg2dec->picture, 0, sizeof (picture_t));
/* initialize substructures */
@@ -236,7 +243,7 @@ static void remember_metainfo (mpeg2dec_
}
static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
- uint8_t * buffer)
+ uint8_t * buffer, int next_code)
{
picture_t * picture;
int is_frame_done;
@@ -303,6 +310,10 @@ static inline int parse_chunk (mpeg2dec_
abort();
}
+/* reset picture AFD data and set index to picture */
+mpeg2dec->afd_stack[2] = -1;
+mpeg2dec->afd_index = 2;
+
mpeg2dec->is_frame_needed=0;
if (!picture->second_field) {
@@ -393,6 +404,17 @@ static inline int parse_chunk (mpeg2dec_
/* abort(); */
break;
}
+
+/* reset squence, group and picture AFD data and set index to sequence */
+mpeg2dec->afd_stack[0] = -1;
+mpeg2dec->afd_stack[1] = -1;
+mpeg2dec->afd_stack[2] = -1;
+mpeg2dec->afd_index = 0;
+
+/* according to ISO/IEC 13818-2, an extension start code will follow.
+ * Otherwise the stream follows ISO/IEC 11172-2 which means MPEG1 */
+picture->mpeg1 = (next_code != 0xb5);
+
if (mpeg2dec->force_aspect) picture->aspect_ratio_information = mpeg2dec->force_aspect;
if (mpeg2dec->is_sequence_needed ) {
@@ -457,6 +479,12 @@ static inline int parse_chunk (mpeg2dec_
printf ("libmpeg2: bad group of pictures\n");
abort();
}
+
+/* reset group and picture AFD data and set index to group */
+mpeg2dec->afd_stack[1] = -1;
+mpeg2dec->afd_stack[2] = -1;
+mpeg2dec->afd_index = 1;
+
default:
if ((code >= 0xb9) && (code != 0xe4)) {
printf("Not multiplexed? 0x%x\n",code);
@@ -464,6 +492,22 @@ static inline int parse_chunk (mpeg2dec_
if (code >= 0xb0)
break;
+/* check for AFD change once per picture */
+if (0 <= mpeg2dec->afd_index && mpeg2dec->afd_index <= 2) {
+int afd = (mpeg2dec->afd_stack[2] == -1) ? (mpeg2dec->afd_stack[1] == -1) ? mpeg2dec->afd_stack[0] : mpeg2dec->afd_stack[1] : mpeg2dec->afd_stack[2];
+mpeg2dec->afd_index = -1;
+/* AFD data should better be stored in current_frame to have it */
+/* ready and synchronous with other data like width or height. */
+/* An AFD change should then be detected when a new frame is emitted */
+/* from the decoder to report the AFD change in display order and not */
+/* in decoding order like it happens below for now. */
+if (mpeg2dec->afd_value != afd) {
+mpeg2dec->afd_value = afd;
+_x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_VIDEO_AFD, mpeg2dec->afd_value);
+fprintf(stderr, "AFD changed to: %d\n", afd);
+}
+}
+
if (!(mpeg2dec->in_slice)) {
mpeg2dec->in_slice = 1;
@@ -574,45 +618,135 @@ static inline int parse_chunk (mpeg2dec_
return is_frame_done;
}
+static inline int find_start_code (mpeg2dec_t * mpeg2dec,
+ uint8_t ** current, uint8_t * limit)
+{
+uint8_t * p;
+
+if (*current >= limit)
+ return 0;
+